aboutsummaryrefslogtreecommitdiff
path: root/lld/test
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2024-05-31 09:31:15 -0700
committerGitHub <noreply@github.com>2024-05-31 09:31:15 -0700
commit7b6a89f346f281e5b7caa593a8c484eaf4264055 (patch)
tree33243cd4f241bf3976ac37e0a387214dcbf3017c /lld/test
parent98d5d3448d9ddc6fb07855eb45a08652bd530c01 (diff)
downloadllvm-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.s4
-rw-r--r--lld/test/ELF/linkerscript/section-not-converge.test37
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;
+}