Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -26,7 +26,8 @@ template class OutputSectionFactory; template class DefinedCommon; -typedef std::function Expr; +typedef std::function DotExpr; +typedef std::function Expr; // Parses a linker script. Calling this function updates // Config and ScriptConfig. Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -220,12 +220,14 @@ uintX_t MinVA = std::numeric_limits::max(); uintX_t ThreadBssOffset = 0; + auto LocationCounter = [=]() { return Dot; }; for (const std::unique_ptr &Base : Opt.Commands) { if (auto *Cmd = dyn_cast(Base.get())) { if (Cmd->Name == ".") { - Dot = Cmd->Expression(Dot); + Dot = Cmd->Expression(LocationCounter); } else if (Cmd->Sym) { - cast>(Cmd->Sym)->Value = Cmd->Expression(Dot); + cast>(Cmd->Sym)->Value = + Cmd->Expression(LocationCounter); } continue; } @@ -239,10 +241,10 @@ continue; if (Cmd->AddrExpr) - Dot = Cmd->AddrExpr(Dot); + Dot = Cmd->AddrExpr(LocationCounter); if (Cmd->AlignExpr) - Sec->updateAlignment(Cmd->AlignExpr(Dot)); + Sec->updateAlignment(Cmd->AlignExpr(LocationCounter)); if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { uintX_t TVA = Dot + ThreadBssOffset; @@ -872,7 +874,7 @@ assert(Op == "=" || Op == "+="); Expr E = readExpr(); if (Op == "+=") - E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); }; + E = [=](DotExpr Dot) { return getSymbolValue(Name, Dot()) + E(Dot); }; auto *Cmd = new SymbolAssignment(Name, E); Opt.Commands.emplace_back(Cmd); return Cmd; @@ -933,13 +935,13 @@ expect("("); Expr E = readExpr(); expect(")"); - return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; + return [=](DotExpr Dot) { return alignTo(Dot(), E(Dot)); }; } if (Tok == "CONSTANT") { expect("("); StringRef Tok = next(); expect(")"); - return [=](uint64_t Dot) { return getConstant(Tok); }; + return [=](DotExpr Dot) { return getConstant(Tok); }; } if (Tok == "SEGMENT_START") { expect("("); @@ -948,7 +950,7 @@ uint64_t Val; next().getAsInteger(0, Val); expect(")"); - return [=](uint64_t Dot) { return Val; }; + return [=](DotExpr Dot) { return Val; }; } if (Tok == "DATA_SEGMENT_ALIGN") { expect("("); @@ -956,13 +958,13 @@ expect(","); readExpr(); expect(")"); - return [=](uint64_t Dot) { return alignTo(Dot, E(Dot)); }; + return [=](DotExpr Dot) { return alignTo(Dot(), E(Dot)); }; } if (Tok == "DATA_SEGMENT_END") { expect("("); expect("."); expect(")"); - return [](uint64_t Dot) { return Dot; }; + return [](DotExpr Dot) { return Dot(); }; } // GNU linkers implements more complicated logic to handle // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and just align to @@ -973,13 +975,13 @@ expect(","); readExpr(); expect(")"); - return [](uint64_t Dot) { return alignTo(Dot, Target->PageSize); }; + return [](DotExpr Dot) { return alignTo(Dot(), Target->PageSize); }; } if (Tok == "SIZEOF") { expect("("); StringRef Name = next(); expect(")"); - return [=](uint64_t Dot) { return getSectionSize(Name); }; + return [=](DotExpr Dot) { return getSectionSize(Name); }; } // Parse a symbol name or a number literal. @@ -987,9 +989,9 @@ if (Tok.getAsInteger(0, V)) { if (Tok != "." && !isValidCIdentifier(Tok)) setError("malformed number: " + Tok); - return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); }; + return [=](DotExpr Dot) { return getSymbolValue(Tok, Dot()); }; } - return [=](uint64_t Dot) { return V; }; + return [=](DotExpr Dot) { return V; }; } Expr ScriptParser::readTernary(Expr Cond) { @@ -997,14 +999,14 @@ Expr L = readExpr(); expect(":"); Expr R = readExpr(); - return [=](uint64_t Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; + return [=](DotExpr Dot) { return Cond(Dot) ? L(Dot) : R(Dot); }; } Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) { if (Op == "*") - return [=](uint64_t Dot) { return L(Dot) * R(Dot); }; + return [=](DotExpr Dot) { return L(Dot) * R(Dot); }; if (Op == "/") { - return [=](uint64_t Dot) -> uint64_t { + return [=](DotExpr Dot) -> uint64_t { uint64_t RHS = R(Dot); if (RHS == 0) { error("division by zero"); @@ -1014,23 +1016,23 @@ }; } if (Op == "+") - return [=](uint64_t Dot) { return L(Dot) + R(Dot); }; + return [=](DotExpr Dot) { return L(Dot) + R(Dot); }; if (Op == "-") - return [=](uint64_t Dot) { return L(Dot) - R(Dot); }; + return [=](DotExpr Dot) { return L(Dot) - R(Dot); }; if (Op == "<") - return [=](uint64_t Dot) { return L(Dot) < R(Dot); }; + return [=](DotExpr Dot) { return L(Dot) < R(Dot); }; if (Op == ">") - return [=](uint64_t Dot) { return L(Dot) > R(Dot); }; + return [=](DotExpr Dot) { return L(Dot) > R(Dot); }; if (Op == ">=") - return [=](uint64_t Dot) { return L(Dot) >= R(Dot); }; + return [=](DotExpr Dot) { return L(Dot) >= R(Dot); }; if (Op == "<=") - return [=](uint64_t Dot) { return L(Dot) <= R(Dot); }; + return [=](DotExpr Dot) { return L(Dot) <= R(Dot); }; if (Op == "==") - return [=](uint64_t Dot) { return L(Dot) == R(Dot); }; + return [=](DotExpr Dot) { return L(Dot) == R(Dot); }; if (Op == "!=") - return [=](uint64_t Dot) { return L(Dot) != R(Dot); }; + return [=](DotExpr Dot) { return L(Dot) != R(Dot); }; if (Op == "&") - return [=](uint64_t Dot) { return L(Dot) & R(Dot); }; + return [=](DotExpr Dot) { return L(Dot) & R(Dot); }; llvm_unreachable("invalid operator"); }