diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -257,10 +257,8 @@ StringRef s = saver.save(config->dynamicLinker); ArrayRef contents = {(const uint8_t *)s.data(), s.size() + 1}; - auto *sec = make(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, contents, - ".interp"); - sec->markLive(); - return sec; + return make(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 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -314,7 +314,18 @@ // 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 = 0; i != partitions.size(); ++i) { + InputSection *sec = createInterpSection(); + sec->partition = i + 1; + inputSections.push_back(sec); + } + } + + auto add = [](SyntheticSection *sec) { inputSections.push_back(sec); }; in.shStrTab = make(".shstrtab", false); @@ -356,7 +367,7 @@ 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 @@ part.relaDyn = make>(relaDynName, config->zCombreloc); - if (needsInterpSection()) - add(createInterpSection()); - if (config->hasDynSymTab) { part.dynSymTab = make>(*part.dynStrTab); add(part.dynSymTab); diff --git a/lld/test/ELF/Inputs/shared.s b/lld/test/ELF/Inputs/shared.s --- 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 --- a/lld/test/ELF/dynamic-linker.s +++ b/lld/test/ELF/dynamic-linker.s @@ -4,11 +4,12 @@ # 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 %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 %s +# CHECK-NOT: .bss # CHECK: [Requesting program interpreter: foo] # RUN: ld.lld %t.o %t.so -o %t diff --git a/lld/test/ELF/partition-dynamic-linker.s b/lld/test/ELF/partition-dynamic-linker.s new file mode 100644 --- /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