[PATCH] D36546: Garbage-collect common symbols.
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 9 15:49:32 PDT 2017
LGTM
Rui Ueyama via Phabricator via llvm-commits
<llvm-commits at lists.llvm.org> writes:
> ruiu updated this revision to Diff 110474.
> ruiu added a comment.
>
> - Address review comment.
>
>
> https://reviews.llvm.org/D36546
>
> Files:
> lld/ELF/MarkLive.cpp
> lld/ELF/Symbols.cpp
> lld/ELF/Symbols.h
> lld/ELF/SyntheticSections.cpp
> lld/ELF/Writer.cpp
> lld/test/ELF/common-gc.s
> lld/test/ELF/common-gc2.s
>
> Index: lld/test/ELF/common-gc2.s
> ===================================================================
> --- /dev/null
> +++ lld/test/ELF/common-gc2.s
> @@ -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
> Index: lld/test/ELF/common-gc.s
> ===================================================================
> --- /dev/null
> +++ lld/test/ELF/common-gc.s
> @@ -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
> Index: lld/ELF/Writer.cpp
> ===================================================================
> --- lld/ELF/Writer.cpp
> +++ lld/ELF/Writer.cpp
> @@ -451,7 +451,11 @@
> 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;
> }
>
> Index: lld/ELF/SyntheticSections.cpp
> ===================================================================
> --- lld/ELF/SyntheticSections.cpp
> +++ lld/ELF/SyntheticSections.cpp
> @@ -77,9 +77,11 @@
> 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;
> }
>
> Index: lld/ELF/Symbols.h
> ===================================================================
> --- lld/ELF/Symbols.h
> +++ lld/ELF/Symbols.h
> @@ -159,13 +159,17 @@
> 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;
> };
>
> Index: lld/ELF/Symbols.cpp
> ===================================================================
> --- lld/ELF/Symbols.cpp
> +++ lld/ELF/Symbols.cpp
> @@ -307,7 +307,7 @@
> 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.
> Index: lld/ELF/MarkLive.cpp
> ===================================================================
> --- lld/ELF/MarkLive.cpp
> +++ lld/ELF/MarkLive.cpp
> @@ -72,17 +72,25 @@
> 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;
> typename ELFT::uint Offset = D->Value;
> 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 @@
> 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 @@
>
> // 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());
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list