Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -1059,6 +1059,11 @@ if (errorCount()) return; + // We want to declare linker script's symbols early, + // so that we can version them. + // They also might be exported if referenced by DSOs. + Script->declareSymbols(); + // Handle undefined symbols in DSOs. if (!Config->Shared) Symtab->scanShlibUndefined(); @@ -1076,10 +1081,6 @@ if (!Config->Relocatable) addReservedSymbols(); - // We want to declare linker script's symbols early, - // so that we can version them. - Script->declareSymbols(); - // Apply version scripts. Symtab->scanVersionScript(); Index: ELF/InputFiles.h =================================================================== --- ELF/InputFiles.h +++ ELF/InputFiles.h @@ -341,6 +341,7 @@ extern std::vector BitcodeFiles; extern std::vector ObjectFiles; extern std::vector SharedFiles; +extern llvm::DenseSet UndefsInShlibs; } // namespace elf } // namespace lld Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -42,6 +42,7 @@ std::vector elf::BitcodeFiles; std::vector elf::ObjectFiles; std::vector elf::SharedFiles; +llvm::DenseSet elf::UndefsInShlibs; TarWriter *elf::Tar; @@ -853,6 +854,7 @@ StringRef Name = CHECK(Sym.getName(this->StringTable), this); if (Sym.isUndefined()) { Undefs.push_back(Name); + UndefsInShlibs.insert(Name); continue; } Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -127,9 +127,12 @@ // If a symbol was in PROVIDE(), we need to define it only // when it is a referenced undefined symbol. Symbol *B = Symtab->find(Cmd->Name); - if (!B || B->isDefined()) - return false; - return true; + if (B && !B->isDefined()) + return true; + // It might also be referenced by a DSO. + if (UndefsInShlibs.find(Cmd->Name) != UndefsInShlibs.end()) + return true; + return false; } // This function is called from processSectionCommands, Index: test/ELF/linkerscript/Inputs/provide-shared2.s =================================================================== --- /dev/null +++ test/ELF/linkerscript/Inputs/provide-shared2.s @@ -0,0 +1,3 @@ +.global foo +.data +.dc.a foo Index: test/ELF/linkerscript/provide-shared2.s =================================================================== --- /dev/null +++ test/ELF/linkerscript/provide-shared2.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/provide-shared2.s -o %t2.o +# RUN: ld.lld %t2.o -o %t2.so -shared +# RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; PROVIDE(foo = 42); }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o %t2.so +# RUN: llvm-readelf --dyn-symbols %t | FileCheck %s + +# CHECK: 1 1: 000000000000002a 0 NOTYPE GLOBAL DEFAULT ABS foo@ + +.global _start +_start: + nop