Skip to content

Commit 9c77d27

Browse files
committedAug 10, 2017
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 llvm-svn: 310617
1 parent 57c681f commit 9c77d27

File tree

7 files changed

+88
-10
lines changed

7 files changed

+88
-10
lines changed
 

‎lld/ELF/MarkLive.cpp

+17-5
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,25 @@ template <class ELFT, class RelT>
7272
static void resolveReloc(InputSectionBase &Sec, RelT &Rel,
7373
std::function<void(ResolvedReloc)> Fn) {
7474
SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
75+
76+
if (auto *Sym = dyn_cast<DefinedCommon>(&B)) {
77+
Sym->Live = true;
78+
return;
79+
}
80+
7581
if (auto *D = dyn_cast<DefinedRegular>(&B)) {
7682
if (!D->Section)
7783
return;
7884
typename ELFT::uint Offset = D->Value;
7985
if (D->isSection())
8086
Offset += getAddend<ELFT>(Sec, Rel);
8187
Fn({cast<InputSectionBase>(D->Section), Offset});
82-
} else if (auto *U = dyn_cast<Undefined>(&B)) {
88+
return;
89+
}
90+
91+
if (auto *U = dyn_cast<Undefined>(&B))
8392
for (InputSectionBase *Sec : CNamedSections.lookup(U->getName()))
8493
Fn({Sec, 0});
85-
}
8694
}
8795

8896
// Calls Fn for each section that Sec refers to via relocations.
@@ -218,10 +226,14 @@ template <class ELFT> void elf::markLive() {
218226
Q.push_back(S);
219227
};
220228

221-
auto MarkSymbol = [&](const SymbolBody *Sym) {
222-
if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym))
229+
auto MarkSymbol = [&](SymbolBody *Sym) {
230+
if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym)) {
223231
if (auto *IS = cast_or_null<InputSectionBase>(D->Section))
224232
Enqueue({IS, D->Value});
233+
return;
234+
}
235+
if (auto *S = dyn_cast_or_null<DefinedCommon>(Sym))
236+
S->Live = true;
225237
};
226238

227239
// Add GC root symbols.
@@ -235,7 +247,7 @@ template <class ELFT> void elf::markLive() {
235247

236248
// Preserve externally-visible symbols if the symbols defined by this
237249
// file can interrupt other ELF file's symbols at runtime.
238-
for (const Symbol *S : Symtab->getSymbols())
250+
for (Symbol *S : Symtab->getSymbols())
239251
if (S->includeInDynsym())
240252
MarkSymbol(S->body());
241253

‎lld/ELF/Symbols.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint32_t Alignment,
273273
uint8_t StOther, uint8_t Type)
274274
: Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther,
275275
Type),
276-
Alignment(Alignment), Size(Size) {}
276+
Live(!Config->GcSections), Alignment(Alignment), Size(Size) {}
277277

278278
// If a shared symbol is referred via a copy relocation, its alignment
279279
// becomes part of the ABI. This function returns a symbol alignment.

‎lld/ELF/Symbols.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,17 @@ class DefinedCommon : public Defined {
161161
return S->kind() == SymbolBody::DefinedCommonKind;
162162
}
163163

164-
// The output offset of this common symbol in the output bss. Computed by the
165-
// writer.
166-
uint64_t Offset;
164+
// True if this symbol is not GC'ed. Liveness is usually a notion of
165+
// input sections and not of symbols, but since common symbols don't
166+
// belong to any input section, their liveness is managed by this bit.
167+
bool Live;
167168

168169
// The maximum alignment we have seen for this symbol.
169170
uint32_t Alignment;
170171

172+
// The output offset of this common symbol in the output bss.
173+
// Computed by the writer.
174+
uint64_t Offset;
171175
uint64_t Size;
172176
};
173177

‎lld/ELF/SyntheticSections.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,11 @@ template <class ELFT> InputSection *elf::createCommonSection() {
7777
return A->Alignment > B->Alignment;
7878
});
7979

80+
// Allocate space for common symbols.
8081
BssSection *Sec = make<BssSection>("COMMON");
8182
for (DefinedCommon *Sym : Syms)
82-
Sym->Offset = Sec->reserveSpace(Sym->Size, Sym->Alignment);
83+
if (Sym->Live)
84+
Sym->Offset = Sec->reserveSpace(Sym->Size, Sym->Alignment);
8385
return Sec;
8486
}
8587

‎lld/ELF/Writer.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,11 @@ static bool includeInSymtab(const SymbolBody &B) {
451451
if (auto *S = dyn_cast<MergeInputSection>(Sec))
452452
if (!S->getSectionPiece(D->Value)->Live)
453453
return false;
454+
return true;
454455
}
456+
457+
if (auto *Sym = dyn_cast<DefinedCommon>(&B))
458+
return Sym->Live;
455459
return true;
456460
}
457461

‎lld/test/ELF/common-gc.s

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# REQUIRES: x86
2+
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3+
4+
# RUN: ld.lld %t -o %t2
5+
# RUN: llvm-readobj -sections -symbols %t2 | FileCheck %s --check-prefix=NOGC
6+
7+
# NOGC: Name: .bss
8+
# NOGC-NEXT: Type:
9+
# NOGC-NEXT: Flags [
10+
# NOGC-NEXT: SHF_ALLOC
11+
# NOGC-NEXT: SHF_WRITE
12+
# NOGC-NEXT: ]
13+
# NOGC-NEXT: Address:
14+
# NOGC-NEXT: Offset:
15+
# NOGC-NEXT: Size: 8
16+
17+
# NOGC: Name: bar
18+
# NOGC: Name: foo
19+
20+
# RUN: ld.lld -gc-sections %t -o %t1
21+
# RUN: llvm-readobj -sections -symbols %t1 | FileCheck %s --check-prefix=GC
22+
23+
# GC: Name: .bss
24+
# GC-NEXT: Type:
25+
# GC-NEXT: Flags [
26+
# GC-NEXT: SHF_ALLOC
27+
# GC-NEXT: SHF_WRITE
28+
# GC-NEXT: ]
29+
# GC-NEXT: Address:
30+
# GC-NEXT: Offset:
31+
# GC-NEXT: Size: 4
32+
33+
# GC-NOT: Name: bar
34+
35+
.comm foo,4,4
36+
.comm bar,4,4
37+
38+
.text
39+
.globl _start
40+
_start:
41+
.quad foo

‎lld/test/ELF/common-gc2.s

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# REQUIRES: x86
2+
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3+
# RUN: ld.lld -gc-sections -export-dynamic %t -o %t1
4+
# RUN: llvm-readobj --dyn-symbols %t1 | FileCheck %s
5+
6+
# CHECK: Name: bar@
7+
# CHECK: Name: foo@
8+
9+
.comm foo,4,4
10+
.comm bar,4,4
11+
12+
.text
13+
.globl _start
14+
_start:
15+
.quad foo

0 commit comments

Comments
 (0)
Please sign in to comment.