-
Notifications
You must be signed in to change notification settings - Fork 15.4k
lld: relocate PHDR if sectionStartMap is not empty #140126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-lld Author: Pavel Skripkin (pskrgag) Changes
To fix it, check PHDR segment when Closes #138584 Full diff: https://github.com/llvm/llvm-project/pull/140126.diff 3 Files Affected:
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.
|
|
@llvm/pr-subscribers-lld-elf Author: Pavel Skripkin (pskrgag) Changes
To fix it, check PHDR segment when Closes #138584 Full diff: https://github.com/llvm/llvm-project/pull/140126.diff 3 Files Affected:
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.
|
| sec->maybeCompress<ELFT>(ctx); | ||
|
|
||
| if (ctx.script->hasSectionsCommand) | ||
| if (ctx.script->hasSectionsCommand || !ctx.arg.sectionStartMap.empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should call allocateHeaders for the additional condition.
The user might specify --section-start to increase the address of a section. It should not change ELF header/program headers behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thanks for review! Closing pr in favor of #140187
LinkerScript::allocateHeaders()checks if PHDR segment is located below minimal virtual address provided in linker script. However user could pass section bases via-Tcommand line argument, which may lead to unsorted (or overlapping) segments in resulting elf.To fix it, check PHDR segment when
sectionStartMapis not empty, which contains bases passed via-TargumentCloses #138584