Index: lld/ELF/ScriptParser.cpp =================================================================== --- lld/ELF/ScriptParser.cpp +++ lld/ELF/ScriptParser.cpp @@ -168,6 +168,13 @@ return 0; } +static ExprValue mod(ExprValue A, ExprValue B) { + if (uint64_t BV = B.getValue()) + return A.getValue() % BV; + error("modulo by zero"); + return 0; +} + static ExprValue bitAnd(ExprValue A, ExprValue B) { moveAbsRight(A, B); return {A.Sec, A.ForceAbsolute, @@ -461,7 +468,7 @@ static int precedence(StringRef Op) { return StringSwitch(Op) - .Cases("*", "/", 5) + .Cases("*", "/", "%", 5) .Cases("+", "-", 4) .Cases("<<", ">>", 3) .Cases("<", "<=", ">", ">=", "==", "!=", 2) @@ -811,6 +818,8 @@ return [=] { return mul(L(), R()); }; if (Op == "/") return [=] { return div(L(), R()); }; + if (Op == "%") + return [=] { return mod(L(), R()); }; if (Op == "<<") return [=] { return L().getValue() << R().getValue(); }; if (Op == ">>") Index: lld/test/ELF/linkerscript/operators.s =================================================================== --- lld/test/ELF/linkerscript/operators.s +++ lld/test/ELF/linkerscript/operators.s @@ -5,6 +5,7 @@ # RUN: plus = 1 + 2 + 3; \ # RUN: minus = 5 - 1; \ # RUN: div = 6 / 2; \ +# RUN: mod = 20 % 7; \ # RUN: mul = 1 + 2 * 3; \ # RUN: nospace = 1+2*6/3; \ # RUN: braces = 1 + (2 + 3) * 4; \ @@ -37,6 +38,7 @@ # CHECK: 00000000000006 *ABS* 00000000 plus # CHECK: 00000000000004 *ABS* 00000000 minus # CHECK: 00000000000003 *ABS* 00000000 div +# CHECK: 00000000000006 *ABS* 00000000 mod # CHECK: 00000000000007 *ABS* 00000000 mul # CHECK: 00000000000005 *ABS* 00000000 nospace # CHECK: 00000000000015 *ABS* 00000000 braces