diff options
author | Fangrui Song <i@maskray.me> | 2024-05-31 09:31:15 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-31 09:31:15 -0700 |
commit | 7b6a89f346f281e5b7caa593a8c484eaf4264055 (patch) | |
tree | 33243cd4f241bf3976ac37e0a387214dcbf3017c /lld/test | |
parent | 98d5d3448d9ddc6fb07855eb45a08652bd530c01 (diff) | |
download | llvm-7b6a89f346f281e5b7caa593a8c484eaf4264055.zip llvm-7b6a89f346f281e5b7caa593a8c484eaf4264055.tar.gz llvm-7b6a89f346f281e5b7caa593a8c484eaf4264055.tar.bz2 |
[ELF] Detect convergence of output section addresses
Some linker scripts don't converge. https://reviews.llvm.org/D66279
("[ELF] Make LinkerScript::assignAddresses iterative") detected
convergence of symbol assignments.
This patch detects convergence of output section addresses. While input
sections might also have convergence issues, they are less common as
expressions that could cause convergence issues typically involve output
sections and symbol assignments.
GNU ld has an error `non constant or forward reference address expression for section` that
correctly rejects
```
SECTIONS {
.text ADDR(.data)+0x1000 : { *(.text) }
.data : { *(.data) }
}
```
but not the following variant:
```
SECTIONS {
.text foo : { *(.text) }
.data : { *(.data) }
foo = ADDR(.data)+0x1000;
}
```
Our approach consistently rejects both cases.
Link: https://discourse.llvm.org/t/lld-and-layout-convergence/79232
Pull Request: https://github.com/llvm/llvm-project/pull/93888
Diffstat (limited to 'lld/test')
-rw-r--r-- | lld/test/ELF/linkerscript/memory-err.s | 4 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/section-not-converge.test | 37 |
2 files changed, 39 insertions, 2 deletions
diff --git a/lld/test/ELF/linkerscript/memory-err.s b/lld/test/ELF/linkerscript/memory-err.s index 98e71e7..5ec190a 100644 --- a/lld/test/ELF/linkerscript/memory-err.s +++ b/lld/test/ELF/linkerscript/memory-err.s @@ -68,8 +68,8 @@ # RUN: symbol = .; \ # RUN: .data : { *(.data) } > ram \ # RUN: }' > %t.script -# RUN: not ld.lld -T %t.script %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR_OVERFLOW %s -# ERR_OVERFLOW: error: section '.data' will not fit in region 'ram': overflowed by 2 bytes +# RUN: not ld.lld -T %t.script %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=NOT_CONVERGE %s +# NOT_CONVERGE: error: address (0x14) of section '.text' does not converge nop diff --git a/lld/test/ELF/linkerscript/section-not-converge.test b/lld/test/ELF/linkerscript/section-not-converge.test new file mode 100644 index 0000000..99e9eeb --- /dev/null +++ b/lld/test/ELF/linkerscript/section-not-converge.test @@ -0,0 +1,37 @@ +# REQUIRES: x86 +# 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 a.lds 2>&1 | FileCheck %s --implicit-check-not=error: +# CHECK: error: address (0x6014) of section '.text' does not converge + +# RUN: ld.lld a.o -T b.lds --noinhibit-exec 2>&1 | FileCheck %s --check-prefix=CHECK2 --implicit-check-not=warning: +# CHECK2: warning: address (0x5014) of section '.text' does not converge +# CHECK2: warning: assignment to symbol a does not converge + +#--- a.s +.globl _start +_start: .space 4 +.data; .byte 0 + +#--- a.lds +SECTIONS { + . = 0x1000; + .text ADDR(.data) + 0x1000 : { *(.text) } + .data : { *(.data) } +} + +#--- b.lds +SECTIONS { + . = 0x1000; + .text text : { *(.text) } + .data : { + *(.data) + x = ADDR(.text); + a = b; + b = c; + ## Absolute symbol; not converging + c = ABSOLUTE(ADDR(.text)); + } + text = ADDR(.data) + 0x1000; +} |