Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -230,7 +230,7 @@ uint64_t getDot() { return Dot; } void discard(ArrayRef V); - ExprValue getSymbolValue(StringRef Name, const Twine &Loc); + ExprValue getSymbolValue(StringRef Name, const Twine &Loc, bool CanUseDot); void fabricateDefaultCommands(); void addOrphanSections(OutputSectionFactory &Factory); Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -402,7 +402,8 @@ // is given, input sections are aligned to that value, whether the // given value is larger or smaller than the original section alignment. if (Sec->SubalignExpr) { - uint32_t Subalign = Sec->SubalignExpr().getValue(); + uint32_t Subalign = + std::max((uint64_t)1, Sec->SubalignExpr().getValue()); for (InputSectionBase *S : V) S->Alignment = Subalign; } @@ -873,9 +874,10 @@ return false; } -ExprValue LinkerScript::getSymbolValue(StringRef Name, const Twine &Loc) { +ExprValue LinkerScript::getSymbolValue(StringRef Name, const Twine &Loc, + bool CanUseDot) { if (Name == ".") { - if (Ctx) + if (CanUseDot) return {Ctx->OutSec, false, Dot - Ctx->OutSec->Addr, Loc}; error(Loc + ": unable to get location counter value"); return 0; Index: ELF/ScriptLexer.h =================================================================== --- ELF/ScriptLexer.h +++ ELF/ScriptLexer.h @@ -38,6 +38,7 @@ std::vector MBs; std::vector Tokens; bool InExpr = false; + bool CanUseDot = false; size_t Pos = 0; private: Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ ELF/ScriptParser.cpp @@ -31,6 +31,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/Support/SaveAndRestore.h" #include #include #include @@ -258,6 +259,7 @@ } else if (Tok == "SEARCH_DIR") { readSearchDir(); } else if (Tok == "SECTIONS") { + SaveAndRestore R(CanUseDot, true); readSections(); } else if (Tok == "VERSION") { readVersion(); @@ -654,8 +656,11 @@ Cmd->LMAExpr = readParenExpr(); if (consume("ALIGN")) Cmd->AlignExpr = readParenExpr(); - if (consume("SUBALIGN")) + if (consume("SUBALIGN")) { + // SUBALIGN expression must be constant, so can't use Dot. + SaveAndRestore R(CanUseDot, false); Cmd->SubalignExpr = readParenExpr(); + } // Parse constraints. if (consume("ONLY_IF_RO")) @@ -756,7 +761,10 @@ Expr E = readExpr(); if (Op == "+=") { std::string Loc = getCurrentLocation(); - E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); }; + bool DotAvailable = CanUseDot; + E = [=] { + return add(Script->getSymbolValue(Name, Loc, DotAvailable), E()); + }; } return make(Name, E, getCurrentLocation()); } @@ -1056,8 +1064,9 @@ return [=] { return elf::getHeaderSize(); }; // Tok is the dot. + bool DotAvailable = CanUseDot; if (Tok == ".") - return [=] { return Script->getSymbolValue(Tok, Location); }; + return [=] { return Script->getSymbolValue(Tok, Location, DotAvailable); }; // Tok is a literal number. if (Optional Val = parseInt(Tok)) @@ -1067,7 +1076,7 @@ if (!isValidCIdentifier(Tok)) setError("malformed number: " + Tok); Script->ReferencedSymbols.push_back(Tok); - return [=] { return Script->getSymbolValue(Tok, Location); }; + return [=] { return Script->getSymbolValue(Tok, Location, DotAvailable); }; } Expr ScriptParser::readTernary(Expr Cond) {