diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -1234,6 +1234,13 @@ error(location + ": undefined section " + cmd->name); } +static bool isValidSymbolName(StringRef s) { + auto valid = [](char c) { + return isAlnum(c) || c == '$' || c == '.' || c == '_'; + }; + return !s.empty() && !isDigit(s[0]) && llvm::all_of(s, valid); +} + Expr ScriptParser::readPrimary() { if (peek() == "(") return readParenExpr(); @@ -1408,7 +1415,7 @@ return [=] { return *val; }; // Tok is a symbol name. - if (!isValidCIdentifier(tok)) + if (!isValidSymbolName(tok)) setError("malformed number: " + tok); script->referencedSymbols.push_back(tok); return [=] { return script->getSymbolValue(tok, location); }; diff --git a/lld/test/ELF/linkerscript/diag3.test b/lld/test/ELF/linkerscript/diag3.test --- a/lld/test/ELF/linkerscript/diag3.test +++ b/lld/test/ELF/linkerscript/diag3.test @@ -5,9 +5,9 @@ SECTIONS { .text : { *(.text) } .keep : { *(.keep) } - boom .temp : { *(.temp) } + boom ^temp : { *(.temp) } } -# CHECK: 8: malformed number: .temp -# CHECK-NEXT: >>> boom .temp : { *(.temp) } +# CHECK: 8: malformed number: ^temp +# CHECK-NEXT: >>> boom ^temp : { *(.temp) } # CHECK-NEXT: >>> ^ diff --git a/lld/test/ELF/linkerscript/diag4.test b/lld/test/ELF/linkerscript/diag4.test --- a/lld/test/ELF/linkerscript/diag4.test +++ b/lld/test/ELF/linkerscript/diag4.test @@ -6,9 +6,9 @@ SECTIONS { .text : { *(.text) } .keep : { *(.keep) } - boom .temp : { *(.temp) } + boom ^temp : { *(.temp) } } -# CHECK: 9: malformed number: .temp -# CHECK-NEXT: >>> boom .temp : { *(.temp) } -# CHECK-NEXT: >>> ^ \ No newline at end of file +# CHECK: 9: malformed number: ^temp +# CHECK-NEXT: >>> boom ^temp : { *(.temp) } +# CHECK-NEXT: >>> ^ diff --git a/lld/test/ELF/linkerscript/diag5.test b/lld/test/ELF/linkerscript/diag5.test --- a/lld/test/ELF/linkerscript/diag5.test +++ b/lld/test/ELF/linkerscript/diag5.test @@ -6,9 +6,9 @@ SECTIONS { .text : { *(.text) } .keep : { *(.keep) } - boom .temp : { *(.temp) } + boom ^temp : { *(.temp) } } -# CHECK: 9: malformed number: .temp -# CHECK-NEXT: >>> boom .temp : { *(.temp) } +# CHECK: 9: malformed number: ^temp +# CHECK-NEXT: >>> boom ^temp : { *(.temp) } # CHECK-NEXT: >>> ^ diff --git a/lld/test/ELF/linkerscript/symbol-name.test b/lld/test/ELF/linkerscript/symbol-name.test new file mode 100644 --- /dev/null +++ b/lld/test/ELF/linkerscript/symbol-name.test @@ -0,0 +1,8 @@ +# REQUIRES: x86 +## Test that . and $ can be used by symbol names in expressions. + +# RUN: llvm-mc -filetype=obj -triple=x86_64 /dev/null -o %t.o +# RUN: ld.lld -T %s %t.o -o /dev/null + +a0 = DEFINED(.TOC.) ? .TOC. : 0; +a1 = DEFINED(__global_pointer$) ? __global_pointer$ : 0;