From 52db9a4fe6757c8c76d1ef205ce4368b3444bf0b Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Mon, 3 Jul 2017 15:49:25 +0000 Subject: [PATCH] [ELF] Remove unused synthetic sections from script commands Script commands are processed before unused synthetic sections are removed. Therefore, if a linker script matches one of these sections it'll get emitted as an empty output section because the logic for removing unused synthetic sections ignores script commands which could have already matched and captured one of these sections. This patch fixes that by also removing the unused synthetic sections from the script commands. Differential Revision: https://reviews.llvm.org/D34800 llvm-svn: 307037 --- lld/ELF/Writer.cpp | 11 ++++++++++- lld/test/ELF/linkerscript/unused-synthetic.s | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 lld/test/ELF/linkerscript/unused-synthetic.s diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 080d8e787301..551ca260de10 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1149,8 +1149,17 @@ static void removeUnusedSyntheticSections(std::vector &V) { SS->Live = false; // If there are no other sections in the output section, remove it from the // output. - if (OS->Sections.empty()) + if (OS->Sections.empty()) { V.erase(std::find(V.begin(), V.end(), OS)); + // Also remove script commands matching the output section. + auto &Cmds = Script->Opt.Commands; + auto I = std::remove_if(Cmds.begin(), Cmds.end(), [&](BaseCommand *Cmd) { + if (auto *OSCmd = dyn_cast(Cmd)) + return OSCmd->Sec == OS; + return false; + }); + Cmds.erase(I, Cmds.end()); + } } } diff --git a/lld/test/ELF/linkerscript/unused-synthetic.s b/lld/test/ELF/linkerscript/unused-synthetic.s new file mode 100644 index 000000000000..c9295fff7b59 --- /dev/null +++ b/lld/test/ELF/linkerscript/unused-synthetic.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: .got : { *(.got) } \ +# RUN: .plt : { *(.plt) } \ +# RUN: .text : { *(.text) } \ +# RUN: }" > %t.script +# RUN: ld.lld -shared -o %t.so --script %t.script %t.o + +# RUN: llvm-objdump -section-headers %t.so | FileCheck %s +# CHECK-NOT: .got +# CHECK-NOT: .plt +# CHECK: .text +# CHECK-NEXT: .dynsym + +.global _start +_start: + nop