Skip to content

Commit 923a3cc

Browse files
authored
[LLD] Fix crash on parsing ':ALIGN' in linker script (#146723)
The linker was crashing due to stack overflow when parsing ':ALIGN' in an output section description. This commit fixes the linker script parser so that the crash does not happen. The root cause of the stack overflow is how we parse expressions (readExpr) in linker script and the behavior of ScriptLexer::expect(...) utility. ScriptLexer::expect does not do anything if errors have already been encountered during linker script parsing. In particular, it never increments the current token position in the script file, even if the current token is the same as the expected token. This causes an infinite call cycle on parsing an expression such as '(4096)' when an error has already been encountered. readExpr() calls readPrimary() readPrimary() calls readParenExpr() readParenExpr(): expect("("); // no-op, current token still points to '(' Expression *E = readExpr(); // The cycle continues... Closes #146722 Signed-off-by: Parth Arora <partaror@qti.qualcomm.com>
1 parent 9c7320e commit 923a3cc

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

lld/ELF/ScriptParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,6 +1229,8 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
12291229
// This is an operator-precedence parser to parse a linker
12301230
// script expression.
12311231
Expr ScriptParser::readExpr() {
1232+
if (atEOF())
1233+
return []() { return 0; };
12321234
// Our lexer is context-aware. Set the in-expression bit so that
12331235
// they apply different tokenization rules.
12341236
SaveAndRestore saved(lexState, State::Expr);
Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
11
# REQUIRES: x86
2-
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o %t.o
3-
# RUN: ld.lld -o %t --script %s %t.o -shared
2+
# RUN: rm -rf %t && split-file %s %t && cd %t
3+
4+
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux /dev/null -o a.o
5+
# RUN: ld.lld --script a.t a.o -shared
46

57
# lld shouldn't crash.
68

9+
#--- a.t
710
SECTIONS { .foo : ALIGN(2M) {} }
11+
12+
# RUN: not ld.lld --script b.t 2>&1 | FileCheck %s --match-full-lines --strict-whitespace
13+
14+
# lld should not crash and report the error properly.
15+
16+
# CHECK:{{.*}} error: b.t:3: malformed number: :
17+
# CHECK:>>> S :ALIGN(4096) {}
18+
# CHECK:>>> ^
19+
20+
#--- b.t
21+
SECTIONS
22+
{
23+
S :ALIGN(4096) {}
24+
}

0 commit comments

Comments
 (0)