Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -192,6 +192,13 @@ return Sections; } +static uint64_t safeAssign(Expr Expr, uint64_t Dot) { + uint64_t Val = Expr(Dot); + if (Val < Dot) + error("location counter may not be moved backwards"); + return Val; +} + template void LinkerScript::assignAddresses( ArrayRef *> Sections) { @@ -213,11 +220,10 @@ for (const std::unique_ptr &Base : Opt.Commands) { if (auto *Cmd = dyn_cast(Base.get())) { - if (Cmd->Name == ".") { - Dot = Cmd->Expression(Dot); - } else if (Cmd->Sym) { + if (Cmd->Name == ".") + Dot = safeAssign(Cmd->Expression, Dot); + else if (Cmd->Sym) cast>(Cmd->Sym)->Value = Cmd->Expression(Dot); - } continue; } @@ -230,7 +236,7 @@ continue; if (Cmd->AddrExpr) - Dot = Cmd->AddrExpr(Dot); + Dot = safeAssign(Cmd->AddrExpr, Dot); if (Cmd->AlignExpr) Sec->updateAlignment(Cmd->AlignExpr(Dot)); Index: test/ELF/linkerscript/linkerscript-locationcounter-backward.s =================================================================== --- test/ELF/linkerscript/linkerscript-locationcounter-backward.s +++ test/ELF/linkerscript/linkerscript-locationcounter-backward.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS { \ +# RUN: . = 0x10000; \ +# RUN: . = . - 1; \ +# RUN: }" > %t.script +# RUN: not ld.lld -shared %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=ERR %s +# ERR: location counter may not be moved backwards +