[lld] lld: relocate PHDR if sectionStartMap is not empty (PR #140126)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 15 12:29:13 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-elf
Author: Pavel Skripkin (pskrgag)
<details>
<summary>Changes</summary>
`LinkerScript::allocateHeaders()` checks if PHDR segment is located below minimal virtual address provided in linker script. However user could pass section bases via `-T` command line argument, which may lead to unsorted (or overlapping) segments in resulting elf.
To fix it, check PHDR segment when `sectionStartMap` is not empty, which contains bases passed via `-T` argument
Closes #<!-- -->138584
---
Full diff: https://github.com/llvm/llvm-project/pull/140126.diff
3 Files Affected:
- (modified) lld/ELF/Writer.cpp (+1-1)
- (modified) lld/test/ELF/sectionstart.s (+24)
- (modified) lld/test/ELF/ttext-tdata-tbss.s (-2)
``````````diff
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 28b24f90716b8..a11bc76a0fd18 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -331,7 +331,7 @@ template <class ELFT> void Writer<ELFT>::run() {
for (OutputSection *sec : ctx.outputSections)
sec->maybeCompress<ELFT>(ctx);
- if (ctx.script->hasSectionsCommand)
+ if (ctx.script->hasSectionsCommand || !ctx.arg.sectionStartMap.empty())
ctx.script->allocateHeaders(ctx.mainPart->phdrs);
// Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
diff --git a/lld/test/ELF/sectionstart.s b/lld/test/ELF/sectionstart.s
index d694c9375fd80..8eb50263fe6aa 100644
--- a/lld/test/ELF/sectionstart.s
+++ b/lld/test/ELF/sectionstart.s
@@ -11,6 +11,30 @@
# CHECK-NEXT: 2 .data 00000004 0000000000110000 DATA
# CHECK-NEXT: 3 .bss 00000004 0000000000200000 BSS
+## Check that PHDRS are allocated below .text if .text is below default
+## base for non-pie case
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -Ttext=0x3000 -o %t
+# RUN: llvm-readelf -l %t | FileCheck --check-prefix=CHECK-TEXT %s
+
+# CHECK-TEXT: Program Headers:
+# CHECK-TEXT-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
+# CHECK-TEXT-NEXT: PHDR 0x000040 0x0000000000002040 0x0000000000002040 0x000118 0x000118 R 0x8
+# CHECK-TEXT-NEXT: LOAD 0x000000 0x0000000000002000 0x0000000000002000 0x000158 0x000158 R 0x1000
+# CHECK-TEXT-NEXT: LOAD 0x001000 0x0000000000003000 0x0000000000003000 0x000001 0x000001 R E 0x1000
+
+## Check that PHDRS are deleted if they don't fit
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -Ttext=0x0 -o %t
+# RUN: llvm-readelf -l %t | FileCheck --check-prefix=CHECK-TEXT-ZERO %s
+
+# CHECK-TEXT-ZERO: Program Headers:
+# CHECK-TEXT-ZERO-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
+# CHECK-TEXT-ZERO-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000001 0x000001 R E 0x1000
+# CHECK-TEXT-ZERO-NEXT: LOAD 0x001001 0x0000000000001001 0x0000000000001001 0x000004 0x000008 RW 0x1000
+
## The same, but dropped "0x" prefix.
# RUN: ld.lld %t.o --section-start .text=100000 \
# RUN: --section-start .data=110000 --section-start .bss=0x200000 -o %t1
diff --git a/lld/test/ELF/ttext-tdata-tbss.s b/lld/test/ELF/ttext-tdata-tbss.s
index c8254d6969293..01b6e51718b99 100644
--- a/lld/test/ELF/ttext-tdata-tbss.s
+++ b/lld/test/ELF/ttext-tdata-tbss.s
@@ -24,8 +24,6 @@
# USER1-NEXT: .rodata PROGBITS 0000000000009008 002008 000008
# USER1-NEXT: .aw PROGBITS 000000000000a010 002010 000008
# USER1: Type
-# USER1-NEXT: PHDR 0x000040 0x0000000000200040
-# USER1-NEXT: LOAD 0x000000 0x0000000000200000
# USER1-NEXT: LOAD 0x001000 0x0000000000000000
## Specify --image-base to make program headers look normal.
``````````
</details>
https://github.com/llvm/llvm-project/pull/140126
More information about the llvm-commits
mailing list