Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion lld/ELF/LinkerScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1718,6 +1718,13 @@ void LinkerScript::addScriptReferencedSymbolsToSymTable() {
}

bool LinkerScript::shouldAddProvideSym(StringRef symName) {
// This function is called before and after garbage collection. To prevent
// undefined references from the RHS, the result of this function for a
// symbol must be the same for each call. We use isUsedInRegularObj to not
// change the return value of a demoted symbol. The exportDynamic condition,
// while not so accurate, allows PROVIDE to define a symbol referenced by a
// DSO.
Symbol *sym = symtab.find(symName);
return sym && !sym->isDefined() && !sym->isCommon();
return sym && !sym->isDefined() && !sym->isCommon() &&
(sym->isUsedInRegularObj || sym->exportDynamic);
}
36 changes: 36 additions & 0 deletions lld/test/ELF/linkerscript/provide-defined.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# REQUIRES: x86
## Test the GC behavior when the PROVIDE symbol is defined by a relocatable file.

# RUN: rm -rf %t && split-file %s %t && cd %t
# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o
# RUN: llvm-mc -filetype=obj -triple=x86_64 b.s -o b.o
# RUN: ld.lld -T a.t --gc-sections a.o b.o -o a
# RUN: llvm-readelf -s a | FileCheck %s

# CHECK: 1: {{.*}} 0 NOTYPE GLOBAL DEFAULT 1 _start
# CHECK-NEXT:2: {{.*}} 0 NOTYPE GLOBAL DEFAULT 2 f3
# CHECK-NOT: {{.}}

#--- a.s
.global _start, f1, f2, f3, bar
_start:
call f3

.section .text.f1,"ax"; f1:
.section .text.f2,"ax"; f2: # referenced by another relocatable file
.section .text.f3,"ax"; f3: # live
.section .text.bar,"ax"; bar:

.comm comm,4,4

#--- b.s
call f2

#--- a.t
SECTIONS {
. = . + SIZEOF_HEADERS;
PROVIDE(f1 = bar+1);
PROVIDE(f2 = bar+2);
PROVIDE(f3 = bar+3);
PROVIDE(f4 = comm+4);
}
Loading