[lld] r310617 - Garbage-collect common symbols.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 10 08:54:27 PDT 2017
Author: ruiu
Date: Thu Aug 10 08:54:27 2017
New Revision: 310617
URL: http://llvm.org/viewvc/llvm-project?rev=310617&view=rev
Log:
Garbage-collect common symbols.
Liveness is usually a notion of input sections, but this patch adds
"liveness" bit to common symbols because they don't belong to any
input section.
This patch is based on https://reviews.llvm.org/D36520
Differential Revision: https://reviews.llvm.org/D36546
Added:
lld/trunk/test/ELF/common-gc.s
lld/trunk/test/ELF/common-gc2.s
Modified:
lld/trunk/ELF/MarkLive.cpp
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/Symbols.h
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=310617&r1=310616&r2=310617&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Thu Aug 10 08:54:27 2017
@@ -72,6 +72,12 @@ template <class ELFT, class RelT>
static void resolveReloc(InputSectionBase &Sec, RelT &Rel,
std::function<void(ResolvedReloc)> Fn) {
SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
+
+ if (auto *Sym = dyn_cast<DefinedCommon>(&B)) {
+ Sym->Live = true;
+ return;
+ }
+
if (auto *D = dyn_cast<DefinedRegular>(&B)) {
if (!D->Section)
return;
@@ -79,10 +85,12 @@ static void resolveReloc(InputSectionBas
if (D->isSection())
Offset += getAddend<ELFT>(Sec, Rel);
Fn({cast<InputSectionBase>(D->Section), Offset});
- } else if (auto *U = dyn_cast<Undefined>(&B)) {
+ return;
+ }
+
+ if (auto *U = dyn_cast<Undefined>(&B))
for (InputSectionBase *Sec : CNamedSections.lookup(U->getName()))
Fn({Sec, 0});
- }
}
// Calls Fn for each section that Sec refers to via relocations.
@@ -218,10 +226,14 @@ template <class ELFT> void elf::markLive
Q.push_back(S);
};
- auto MarkSymbol = [&](const SymbolBody *Sym) {
- if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym))
+ auto MarkSymbol = [&](SymbolBody *Sym) {
+ if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym)) {
if (auto *IS = cast_or_null<InputSectionBase>(D->Section))
Enqueue({IS, D->Value});
+ return;
+ }
+ if (auto *S = dyn_cast_or_null<DefinedCommon>(Sym))
+ S->Live = true;
};
// Add GC root symbols.
@@ -235,7 +247,7 @@ template <class ELFT> void elf::markLive
// 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->getSymbols())
+ for (Symbol *S : Symtab->getSymbols())
if (S->includeInDynsym())
MarkSymbol(S->body());
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=310617&r1=310616&r2=310617&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Thu Aug 10 08:54:27 2017
@@ -273,7 +273,7 @@ DefinedCommon::DefinedCommon(StringRef N
uint8_t StOther, uint8_t Type)
: Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther,
Type),
- Alignment(Alignment), Size(Size) {}
+ Live(!Config->GcSections), Alignment(Alignment), Size(Size) {}
// If a shared symbol is referred via a copy relocation, its alignment
// becomes part of the ABI. This function returns a symbol alignment.
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=310617&r1=310616&r2=310617&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Thu Aug 10 08:54:27 2017
@@ -161,13 +161,17 @@ public:
return S->kind() == SymbolBody::DefinedCommonKind;
}
- // The output offset of this common symbol in the output bss. Computed by the
- // writer.
- uint64_t Offset;
+ // True if this symbol is not GC'ed. Liveness is usually a notion of
+ // input sections and not of symbols, but since common symbols don't
+ // belong to any input section, their liveness is managed by this bit.
+ bool Live;
// The maximum alignment we have seen for this symbol.
uint32_t Alignment;
+ // The output offset of this common symbol in the output bss.
+ // Computed by the writer.
+ uint64_t Offset;
uint64_t Size;
};
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=310617&r1=310616&r2=310617&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Thu Aug 10 08:54:27 2017
@@ -77,9 +77,11 @@ template <class ELFT> InputSection *elf:
return A->Alignment > B->Alignment;
});
+ // Allocate space for common symbols.
BssSection *Sec = make<BssSection>("COMMON");
for (DefinedCommon *Sym : Syms)
- Sym->Offset = Sec->reserveSpace(Sym->Size, Sym->Alignment);
+ if (Sym->Live)
+ Sym->Offset = Sec->reserveSpace(Sym->Size, Sym->Alignment);
return Sec;
}
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=310617&r1=310616&r2=310617&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Aug 10 08:54:27 2017
@@ -451,7 +451,11 @@ static bool includeInSymtab(const Symbol
if (auto *S = dyn_cast<MergeInputSection>(Sec))
if (!S->getSectionPiece(D->Value)->Live)
return false;
+ return true;
}
+
+ if (auto *Sym = dyn_cast<DefinedCommon>(&B))
+ return Sym->Live;
return true;
}
Added: lld/trunk/test/ELF/common-gc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/common-gc.s?rev=310617&view=auto
==============================================================================
--- lld/trunk/test/ELF/common-gc.s (added)
+++ lld/trunk/test/ELF/common-gc.s Thu Aug 10 08:54:27 2017
@@ -0,0 +1,41 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+
+# RUN: ld.lld %t -o %t2
+# RUN: llvm-readobj -sections -symbols %t2 | FileCheck %s --check-prefix=NOGC
+
+# NOGC: Name: .bss
+# NOGC-NEXT: Type:
+# NOGC-NEXT: Flags [
+# NOGC-NEXT: SHF_ALLOC
+# NOGC-NEXT: SHF_WRITE
+# NOGC-NEXT: ]
+# NOGC-NEXT: Address:
+# NOGC-NEXT: Offset:
+# NOGC-NEXT: Size: 8
+
+# NOGC: Name: bar
+# NOGC: Name: foo
+
+# RUN: ld.lld -gc-sections %t -o %t1
+# RUN: llvm-readobj -sections -symbols %t1 | FileCheck %s --check-prefix=GC
+
+# GC: Name: .bss
+# GC-NEXT: Type:
+# GC-NEXT: Flags [
+# GC-NEXT: SHF_ALLOC
+# GC-NEXT: SHF_WRITE
+# GC-NEXT: ]
+# GC-NEXT: Address:
+# GC-NEXT: Offset:
+# GC-NEXT: Size: 4
+
+# GC-NOT: Name: bar
+
+.comm foo,4,4
+.comm bar,4,4
+
+.text
+.globl _start
+_start:
+ .quad foo
Added: lld/trunk/test/ELF/common-gc2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/common-gc2.s?rev=310617&view=auto
==============================================================================
--- lld/trunk/test/ELF/common-gc2.s (added)
+++ lld/trunk/test/ELF/common-gc2.s Thu Aug 10 08:54:27 2017
@@ -0,0 +1,15 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+# RUN: ld.lld -gc-sections -export-dynamic %t -o %t1
+# RUN: llvm-readobj --dyn-symbols %t1 | FileCheck %s
+
+# CHECK: Name: bar@
+# CHECK: Name: foo@
+
+.comm foo,4,4
+.comm bar,4,4
+
+.text
+.globl _start
+_start:
+ .quad foo
More information about the llvm-commits
mailing list