forked from OSchip/llvm-project
[ELF] Support . and $ in symbol names in expressions
GNU ld supports `.` and `$` in symbol names while LLD doesn't support them in `readPrimary` expressions. Using `.` can result in such an error: ``` https://github.com/ClangBuiltLinux/linux/issues/1318 ld.lld: error: ./arch/powerpc/kernel/vmlinux.lds:255: malformed number: .TOC. >>> __toc_ptr = (DEFINED (.TOC.) ? .TOC. : ADDR (.got)) + 0x8000; ``` Allow `.` (ppc64 special symbol `.TOC.`) and `$` (RISC-V special symbol `__global_pointer$`). Change `diag[3-5].test` to use an invalid character `^`. Note: GNU ld allows `~` in non-leading positions of a symbol name. `~` is not used in practice, conflicts with the unary operator, and can cause some parsing difficulty, so this patch does not add it. Differential Revision: https://reviews.llvm.org/D98306
This commit is contained in:
parent
9c841cb8e8
commit
e4f385d894
|
@ -1234,6 +1234,13 @@ static void checkIfExists(OutputSection *cmd, StringRef location) {
|
|||
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 @@ Expr ScriptParser::readPrimary() {
|
|||
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); };
|
||||
|
|
|
@ -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: >>> ^
|
||||
|
|
|
@ -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: >>> ^
|
||||
# CHECK: 9: malformed number: ^temp
|
||||
# CHECK-NEXT: >>> boom ^temp : { *(.temp) }
|
||||
# CHECK-NEXT: >>> ^
|
||||
|
|
|
@ -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: >>> ^
|
||||
|
|
|
@ -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;
|
Loading…
Reference in New Issue