diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 0300b956e6071..c52982d525237 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -1157,6 +1157,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef tok) { return make(".", readAssert(), 0, getCurrentLocation()); const char *oldS = prevTok.data(); + const char *oldBufBegin = curBuf.begin; SymbolAssignment *cmd = nullptr; bool savedSeenRelroEnd = ctx.script->seenRelroEnd; const StringRef op = peek(); @@ -1179,8 +1180,13 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef tok) { if (cmd) { cmd->dataSegmentRelroEnd = !savedSeenRelroEnd && ctx.script->seenRelroEnd; - cmd->commandString = StringRef(oldS, curTok.data() - oldS).str(); - squeezeSpaces(cmd->commandString); + // If the inner buffer of an INCLUDE was exhausted while reading the + // expression, oldS lives in a popped buffer and the [oldS, curTok) span is + // not a valid pointer range. + if (curBuf.begin == oldBufBegin) { + cmd->commandString = StringRef(oldS, curTok.data() - oldS).str(); + squeezeSpaces(cmd->commandString); + } expect(";"); } return cmd; diff --git a/lld/test/ELF/linkerscript/include-mid-assignment.s b/lld/test/ELF/linkerscript/include-mid-assignment.s new file mode 100644 index 0000000000000..783e795bb4c77 --- /dev/null +++ b/lld/test/ELF/linkerscript/include-mid-assignment.s @@ -0,0 +1,31 @@ +# REQUIRES: x86 +## When recording `commandString`, an assignment in an INCLUDEd linker script +## that is missing the trailing ';' must not crash lld. Same for a PROVIDE +## whose inner buffer is exhausted before the closing ')'. + +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o +# RUN: not ld.lld a.o -T outer.lds 2>&1 | FileCheck %s +# RUN: not ld.lld a.o -T outer2.lds 2>&1 | FileCheck %s --check-prefix=CHECK2 + +# CHECK: error: outer.lds:2: ; expected, but got {{.*}} +# CHECK2: error: outer2.lds:2: ) expected, but got {{.*}} + +#--- outer.lds +INCLUDE "inc.lds" +SECTIONS { .text : { *(.text*) } } + +#--- inc.lds +foo = 1 + +#--- outer2.lds +INCLUDE "inc2.lds" +SECTIONS { .text : { *(.text*) } } + +#--- inc2.lds +PROVIDE(bar = 1 + +#--- a.s +.globl _start +_start: + ret