Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -878,6 +878,8 @@ SymbolBody &Body = Sec.getFile()->getRelocTargetSym(Rel); RelType Type = Rel.getType(Config->IsMips64EL); + Body.IsUsedInReloc = true; + // Deal with MIPS oddity. if (Config->MipsN32Abi) Type = getMipsN32RelType(I, End); Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -129,6 +129,9 @@ unsigned IsPreemptible : 1; + // True if this symbol is referenced by some relocation. + unsigned IsUsedInReloc : 1; + // The following fields have the same meaning as the ELF symbol attributes. uint8_t Type; // symbol type uint8_t StOther; // st_other field value Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -123,8 +123,8 @@ uint8_t Type) : SymbolKind(K), IsLocal(IsLocal), NeedsPltAddr(false), IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), - IsInIgot(false), IsPreemptible(false), Type(Type), StOther(StOther), - Name(Name) {} + IsInIgot(false), IsPreemptible(false), IsUsedInReloc(false), Type(Type), + StOther(StOther), Name(Name) {} // Returns true if this is a weak undefined symbol. bool SymbolBody::isUndefWeak() const { Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1279,6 +1279,11 @@ InX::SymTab->addSymbol(Body); if (InX::DynSymTab && S->includeInDynsym()) { + if (Body->isUndefined() && !Body->IsUsedInReloc) + // This symbol was most probably used in a section, which was collected + // in the GC phase. We don't need such symbols in the dynamic symbols + // table because they solely introduce useless dependencies. + continue; InX::DynSymTab->addSymbol(Body); if (auto *SS = dyn_cast(Body)) if (cast>(S->File)->isNeeded()) Index: test/ELF/gc-collect-undefined.s =================================================================== --- /dev/null +++ test/ELF/gc-collect-undefined.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %tout --gc-sections -shared +# RUN: llvm-nm -D %tout | FileCheck %s + +# CHECK: bar +# CHECK-NOT: qux + + .global foo,bar,qux + .local baz + + .section .data.foo,"aw",%progbits +foo: + .dc.a bar + + .section .bata.baz,"aw",%progbits +baz: + .dc.a qux Index: test/ELF/gnu-hash-table.s =================================================================== --- test/ELF/gnu-hash-table.s +++ test/ELF/gnu-hash-table.s @@ -1,6 +1,6 @@ # REQUIRES: x86,ppc -# RUN: echo ".globl foo" > %te.s +# RUN: echo ".globl foo; .data; .dc.a foo" > %te.s # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %te.s -o %te-i386.o # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t-i386.o # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t-x86_64.o @@ -244,3 +244,5 @@ bar: .weak zed .global xyz +.data + .dc.a baz Index: test/ELF/lto/shlib-undefined.ll =================================================================== --- test/ELF/lto/shlib-undefined.ll +++ test/ELF/lto/shlib-undefined.ll @@ -1,6 +1,6 @@ ; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o -; RUN: echo .global __progname > %t2.s +; RUN: echo ".global __progname; .data; .dc.a __progname" > %t2.s ; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o ; RUN: ld.lld -shared %t2.o -o %t2.so ; RUN: ld.lld -o %t %t.o %t2.so Index: test/ELF/progname.s =================================================================== --- test/ELF/progname.s +++ test/ELF/progname.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: echo .global __progname > %t2.s +// RUN: echo ".global __progname; .data; .dc.a __progname" > %t2.s // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld -o %t %t.o %t2.so Index: test/ELF/undef-version-script.s =================================================================== --- test/ELF/undef-version-script.s +++ test/ELF/undef-version-script.s @@ -3,9 +3,6 @@ # RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so # RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s -# This does not match gold's behavior because gold does not create undefined -# symbols in dynsym without an appropriate (e.g. PLT) relocation in the input. - # CHECK: DynamicSymbols [ # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: @ @@ -38,3 +35,6 @@ .global foo .weak bar +.data + .dc.a foo + .dc.a bar Index: test/ELF/weak-undef.s =================================================================== --- test/ELF/weak-undef.s +++ test/ELF/weak-undef.s @@ -28,3 +28,6 @@ .globl _start _start: + +.data + .dc.a foo