[lld] r296723 - Make gc a bit more aggressive.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 1 17:50:35 PST 2017
Author: rafael
Date: Wed Mar 1 19:50:34 2017
New Revision: 296723
URL: http://llvm.org/viewvc/llvm-project?rev=296723&view=rev
Log:
Make gc a bit more aggressive.
We were not gcing any section whose name was a C identifier. Both gold
and bfd only keep those if they are used.
To avoid having to create the __start/__stop symbols early or doing
string lookups in resolvedReloc, this patch just looks for undefined
symbols __start/__stop to decide if a section is needed or not.
Added:
lld/trunk/test/ELF/linkerscript/sections-gc2.s
Modified:
lld/trunk/ELF/MarkLive.cpp
lld/trunk/test/ELF/startstop-gccollect.s
Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=296723&r1=296722&r2=296723&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Wed Mar 1 19:50:34 2017
@@ -170,12 +170,7 @@ template <class ELFT> static bool isRese
if (!(Sec->Flags & SHF_ALLOC))
return true;
- // We do not want to reclaim sections if they can be referred
- // by __start_* and __stop_* symbols.
StringRef S = Sec->Name;
- if (isValidCIdentifier(S))
- return true;
-
return S.startswith(".ctors") || S.startswith(".dtors") ||
S.startswith(".init") || S.startswith(".fini") ||
S.startswith(".jcr");
@@ -226,11 +221,22 @@ template <class ELFT> void elf::markLive
for (StringRef S : Config->Undefined)
MarkSymbol(Symtab<ELFT>::X->find(S));
+ // Remember which __start_* or __stop_* symbols are used so that we don't gc
+ // those sections.
+ DenseSet<StringRef> UsedStartStopNames;
+
// Preserve externally-visible symbols if the symbols defined by this
// file can interrupt other ELF file's symbols at runtime.
- for (const Symbol *S : Symtab<ELFT>::X->getSymbols())
- if (S->includeInDynsym())
+ for (const Symbol *S : Symtab<ELFT>::X->getSymbols()) {
+ if (auto *U = dyn_cast_or_null<Undefined>(S->body())) {
+ StringRef Name = U->getName();
+ for (StringRef Prefix : {"__start_", "__stop_"})
+ if (Name.startswith(Prefix))
+ UsedStartStopNames.insert(Name.substr(Prefix.size()));
+ } else if (S->includeInDynsym()) {
MarkSymbol(S->body());
+ }
+ }
// Preserve special sections and those which are specified in linker
// script KEEP command.
@@ -240,7 +246,8 @@ template <class ELFT> void elf::markLive
// referred by .eh_frame here.
if (auto *EH = dyn_cast_or_null<EhInputSection<ELFT>>(Sec))
scanEhFrameSection<ELFT>(*EH, Enqueue);
- if (isReserved<ELFT>(Sec) || Script<ELFT>::X->shouldKeep(Sec))
+ if (isReserved<ELFT>(Sec) || Script<ELFT>::X->shouldKeep(Sec) ||
+ UsedStartStopNames.count(Sec->Name))
Enqueue({Sec, 0});
}
Added: lld/trunk/test/ELF/linkerscript/sections-gc2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/sections-gc2.s?rev=296723&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/sections-gc2.s (added)
+++ lld/trunk/test/ELF/linkerscript/sections-gc2.s Wed Mar 1 19:50:34 2017
@@ -0,0 +1,37 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: echo "SECTIONS { \
+# RUN: used_in_reloc : { *(used_in_reloc) } \
+# RUN: used_in_script : { *(used_in_script) } \
+# RUN: .data : { *(.data) } \
+# RUN: }" > %t.script
+# RUN: ld.lld -T %t.script -o %t.so %t.o -shared --gc-sections
+# RUN: llvm-objdump -h %t.so | FileCheck %s
+
+# CHECK: Idx Name Size Address Type
+# CHECK-NEXT: 0
+# CHECK-NEXT: used_in_reloc
+# CHECK-NEXT: .dynsym
+# CHECK-NEXT: .hash
+# CHECK-NEXT: .dynstr
+# CHECK-NEXT: .rela.dyn
+# CHECK-NEXT: .data
+# CHECK-NEXT: .dynamic
+# CHECK-NEXT: .comment
+# CHECK-NEXT: .symtab
+# CHECK-NEXT: .shstrtab
+# CHECK-NEXT: .strtab
+
+ .data
+ .global foo
+foo:
+ .quad __start_used_in_reloc
+
+ .section unused,"a"
+ .quad 0
+
+ .section used_in_script,"a"
+ .quad 0
+
+ .section used_in_reloc,"a"
+ .quad 0
Modified: lld/trunk/test/ELF/startstop-gccollect.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/startstop-gccollect.s?rev=296723&r1=296722&r2=296723&view=diff
==============================================================================
--- lld/trunk/test/ELF/startstop-gccollect.s (original)
+++ lld/trunk/test/ELF/startstop-gccollect.s Wed Mar 1 19:50:34 2017
@@ -6,24 +6,26 @@
# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
## Check that foo and bar sections are not garbage collected,
-## we do not want to reclaim sections if they can be referred
+## we do not want to reclaim sections if they are referred
## by __start_* and __stop_* symbols.
# RUN: ld.lld %t --gc-sections -o %tout
# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
# DISASM: _start:
-# DISASM-NEXT: 201000: 90 nop
+# DISASM-NEXT: 201000: e8 05 00 00 00 callq 5 <__start_foo>
+# DISASM-NEXT: 201005: e8 01 00 00 00 callq 1 <__start_bar>
# DISASM-NEXT: Disassembly of section foo:
-# DISASM-NEXT: foo:
-# DISASM-NEXT: 201001: 90 nop
+# DISASM-NEXT: __start_foo:
+# DISASM-NEXT: 20100a: 90 nop
# DISASM-NEXT: Disassembly of section bar:
-# DISASM-NEXT: bar:
-# DISASM-NEXT: 201002: 90 nop
+# DISASM-NEXT: __start_bar:
+# DISASM-NEXT: 20100b: 90 nop
.global _start
.text
_start:
- nop
+ callq __start_foo
+ callq __start_bar
.section foo,"ax"
nop
More information about the llvm-commits
mailing list