The lexer maintains a stack of buffers, which allows a construct started in an INCLUDE'd file to be closed by the parent. This produces spurious acceptance of malformed scripts (e.g. a bare assignment with no trailing `;` in the include, terminated by the parent's `;` after `INCLUDE`) and undefined-behavior span computations in `readAssignment`'s `commandString` (issue #190376). Force each INCLUDE to fully parse its own content, similar to a call stack frame. `ScriptLexer::lex` no longer auto-pops on EOF; the `buffers` member is gone. `readInclude` takes a `function_ref<void()>` callback, and the four call sites (top-level, SECTIONS, output section, MEMORY) pass a context-appropriate parser. With this, each buffer contains complete parser structures by construction, so the `[oldS, curTok)` pointer range in `readAssignment` no longer needs a guard.
63 lines
1.6 KiB
Plaintext
63 lines
1.6 KiB
Plaintext
# REQUIRES: x86
|
|
## Test INCLUDE inside SECTIONS { ... }.
|
|
|
|
# RUN: rm -rf %t && split-file %s %t && cd %t
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o
|
|
|
|
## Empty include file.
|
|
# RUN: cp empty.lds inc.lds
|
|
# RUN: ld.lld -T a.lds a.o -o out
|
|
# RUN: llvm-objdump --section-headers out | FileCheck %s --check-prefix=CHECK1
|
|
# CHECK1: .data 00000008 0000000000002000 DATA
|
|
# CHECK1-NEXT: .data3 00000008 0000000000002008 DATA
|
|
|
|
## Non-empty include file.
|
|
# RUN: cp full.lds inc.lds
|
|
# RUN: ld.lld -T a.lds a.o -o out
|
|
# RUN: llvm-objdump --section-headers out | FileCheck %s --check-prefix=CHECK2
|
|
# CHECK2: .data 00000008 0000000000002000 DATA
|
|
# CHECK2-NEXT: .data2 00000008 0000000000002008 DATA
|
|
# CHECK2-NEXT: .data3 00000008 0000000000002010 DATA
|
|
|
|
## An unclosed output section in the include cannot be closed by the outer
|
|
## SECTIONS { ... } '}'.
|
|
# RUN: cp trunc.lds inc.lds
|
|
# RUN: not ld.lld -T a.lds a.o 2>&1 | FileCheck %s --check-prefix=TRUNC
|
|
# TRUNC: error: inc.lds:1: unexpected EOF
|
|
|
|
## A stray '}' in the include cannot close the parent SECTIONS { ... }.
|
|
# RUN: cp brace.lds inc.lds
|
|
# RUN: not ld.lld -T a.lds a.o 2>&1 | FileCheck %s --check-prefix=BRACE
|
|
# BRACE: error: inc.lds:1: unexpected EOF
|
|
|
|
#--- a.s
|
|
.global _start
|
|
_start: nop
|
|
|
|
.section .data,"aw"
|
|
.quad 0
|
|
|
|
#--- a.lds
|
|
MEMORY {
|
|
ROM (rwx): ORIGIN = 0x1000, LENGTH = 0x100
|
|
RAM (rwx): ORIGIN = 0x2000, LENGTH = 0x100
|
|
}
|
|
|
|
SECTIONS {
|
|
.text : { *(.text*) } > ROM
|
|
.data : { *(.data*) } > RAM
|
|
INCLUDE "inc.lds"
|
|
.data3 : { QUAD(0) } > RAM
|
|
}
|
|
|
|
#--- empty.lds
|
|
|
|
#--- full.lds
|
|
.data2 : { QUAD(0) } > RAM
|
|
|
|
#--- trunc.lds
|
|
.text : { *(.text*)
|
|
|
|
#--- brace.lds
|
|
}
|