summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2019-10-01 16:10:13 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2019-10-01 16:10:13 +0000
commit0bb825d20880003c50c9c1a5985db6bc54e57b26 (patch)
tree216f6b2dfd964d393472021c43ec8508d0f66f5d
parente53680002228149efd8fd7d7ca9b9e1612504a9e (diff)
downloadbcm5719-llvm-0bb825d20880003c50c9c1a5985db6bc54e57b26.tar.gz
bcm5719-llvm-0bb825d20880003c50c9c1a5985db6bc54e57b26.zip
ELF: Add .interp synthetic sections first in createSyntheticSections().
Our .interp section is not a SyntheticSection. As a result, it terminates the loop in removeUnusedSyntheticSections(). This has at least two consequences: - The synthetic .bss and .bss.rel.ro sections are always present in dynamically linked executables, even when they are not needed. - The synthetic .ARM.exidx (and possibly other) sections are always present in partitions other than the last one, even when not needed. .ARM.exidx in particular is problematic because it assumes that its list of code sections is non-empty in getLinkOrderDep(), which can lead to a crash if the partition does not have any code sections. Fix these problems by moving the creation of the .interp sections to the top of createSyntheticSections(). While here, make the code a little less error-prone by changing the add() lambdas to take a SyntheticSection instead of an InputSectionBase. Differential Revision: https://reviews.llvm.org/D68256 llvm-svn: 373347
-rw-r--r--lld/ELF/SyntheticSections.cpp6
-rw-r--r--lld/ELF/Writer.cpp18
-rw-r--r--lld/test/ELF/Inputs/shared.s4
-rw-r--r--lld/test/ELF/dynamic-linker.s4
-rw-r--r--lld/test/ELF/partition-dynamic-linker.s24
5 files changed, 43 insertions, 13 deletions
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index ddfd317c726..5d9ebfb5325 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -257,10 +257,8 @@ InputSection *elf::createInterpSection() {
StringRef s = saver.save(config->dynamicLinker);
ArrayRef<uint8_t> contents = {(const uint8_t *)s.data(), s.size() + 1};
- auto *sec = make<InputSection>(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, contents,
- ".interp");
- sec->markLive();
- return sec;
+ return make<InputSection>(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, contents,
+ ".interp");
}
Defined *elf::addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index c51ef149a93..2ce36079db3 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -314,7 +314,18 @@ template <class ELFT> void elf::createSyntheticSections() {
// you can call lld::elf::main more than once as a library.
memset(&Out::first, 0, sizeof(Out));
- auto add = [](InputSectionBase *sec) { inputSections.push_back(sec); };
+ // Add the .interp section first because it is not a SyntheticSection.
+ // The removeUnusedSyntheticSections() function relies on the
+ // SyntheticSections coming last.
+ if (needsInterpSection()) {
+ for (size_t i = 1; i <= partitions.size(); ++i) {
+ InputSection *sec = createInterpSection();
+ sec->partition = i;
+ inputSections.push_back(sec);
+ }
+ }
+
+ auto add = [](SyntheticSection *sec) { inputSections.push_back(sec); };
in.shStrTab = make<StringTableSection>(".shstrtab", false);
@@ -356,7 +367,7 @@ template <class ELFT> void elf::createSyntheticSections() {
StringRef relaDynName = config->isRela ? ".rela.dyn" : ".rel.dyn";
for (Partition &part : partitions) {
- auto add = [&](InputSectionBase *sec) {
+ auto add = [&](SyntheticSection *sec) {
sec->partition = part.getNumber();
inputSections.push_back(sec);
};
@@ -384,9 +395,6 @@ template <class ELFT> void elf::createSyntheticSections() {
part.relaDyn =
make<RelocationSection<ELFT>>(relaDynName, config->zCombreloc);
- if (needsInterpSection())
- add(createInterpSection());
-
if (config->hasDynSymTab) {
part.dynSymTab = make<SymbolTableSection<ELFT>>(*part.dynStrTab);
add(part.dynSymTab);
diff --git a/lld/test/ELF/Inputs/shared.s b/lld/test/ELF/Inputs/shared.s
index c3c22fe4b4f..4a386be23e2 100644
--- a/lld/test/ELF/Inputs/shared.s
+++ b/lld/test/ELF/Inputs/shared.s
@@ -1,9 +1,9 @@
.global bar
-.type bar, @function
+.type bar, %function
bar:
.global bar2
-.type bar2, @function
+.type bar2, %function
bar2:
.global zed
diff --git a/lld/test/ELF/dynamic-linker.s b/lld/test/ELF/dynamic-linker.s
index 3faf8e8a169..d0da77fab29 100644
--- a/lld/test/ELF/dynamic-linker.s
+++ b/lld/test/ELF/dynamic-linker.s
@@ -4,10 +4,10 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
# RUN: ld.lld --dynamic-linker foo %t.o %t.so -o %t
-# RUN: llvm-readelf -program-headers %t | FileCheck %s
+# RUN: llvm-readelf --program-headers --section-headers %t | FileCheck --implicit-check-not=.bss %s
# RUN: ld.lld --dynamic-linker=foo %t.o %t.so -o %t
-# RUN: llvm-readelf -program-headers %t | FileCheck %s
+# RUN: llvm-readelf --program-headers --section-headers %t | FileCheck --implicit-check-not=.bss %s
# CHECK: [Requesting program interpreter: foo]
diff --git a/lld/test/ELF/partition-dynamic-linker.s b/lld/test/ELF/partition-dynamic-linker.s
new file mode 100644
index 00000000000..f542a35e5e4
--- /dev/null
+++ b/lld/test/ELF/partition-dynamic-linker.s
@@ -0,0 +1,24 @@
+## Test that we don't create a .ARM.exidx for the main partition.
+## Previously we were doing so, which is unnecessary and led to a crash.
+
+# RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/shared.s -o %t1.o
+# RUN: ld.lld -shared %t1.o -o %t.so
+# RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+
+# RUN: ld.lld -shared --gc-sections --dynamic-linker foo %t.o %t.so -o %t
+# RUN: llvm-readelf --section-headers %t | FileCheck %s
+
+# CHECK: .ARM.exidx
+# CHECK-NOT: .ARM.exidx
+
+.section .llvm_sympart,"",%llvm_sympart
+.asciz "part1"
+.4byte p1
+
+.section .text.p1,"ax",%progbits
+.globl p1
+p1:
+.fnstart
+bx lr
+.cantunwind
+.fnend
OpenPOWER on IntegriCloud