Apply different tokenization rules to linker script expressions.
The linker script lexer is context-sensitive. In the regular context,
arithmetic operator characters are regular characters, but in the
expression context, they are independent tokens. This afects how the
lexer tokenizes "3*4", for example. (This kind of expression is real;
the Linux kernel uses it.)
This patch defines function `maybeSplitExpr`. This function splits the
current token into multiple expression tokens if the lexer is in the
expression context.
Differential Revision: https://reviews.llvm.org/D29963
llvm-svn: 295225
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 1405fa5..bcccd29 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -1610,9 +1610,7 @@
Expr E;
assert(Op == "=" || Op == "+=");
if (consume("ABSOLUTE")) {
- // The RHS may be something like "ABSOLUTE(.) & 0xff".
- // Call readExpr1 to read the whole expression.
- E = readExpr1(readParenExpr(), 0);
+ E = readExpr();
E.IsAbsolute = [] { return true; };
} else {
E = readExpr();
@@ -1628,7 +1626,15 @@
// This is an operator-precedence parser to parse a linker
// script expression.
-Expr ScriptParser::readExpr() { return readExpr1(readPrimary(), 0); }
+Expr ScriptParser::readExpr() {
+ // Our lexer is context-aware. Set the in-expression bit so that
+ // they apply different tokenization rules.
+ bool Orig = InExpr;
+ InExpr = true;
+ Expr E = readExpr1(readPrimary(), 0);
+ InExpr = Orig;
+ return E;
+}
static Expr combine(StringRef Op, Expr L, Expr R) {
auto IsAbs = [=] { return L.IsAbsolute() && R.IsAbsolute(); };