Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -84,6 +84,7 @@ llvm::StringMap SectionStartMap; llvm::StringRef Chroot; llvm::StringRef DynamicLinker; + bool HasDynamicList; llvm::StringRef Entry; llvm::StringRef Emulation; llvm::StringRef Fini; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -744,9 +744,11 @@ // symbols private. Note that -export-dynamic takes precedence over them // as it says all symbols should be exported. if (!HasExportDynamic) { - for (auto *Arg : Args.filtered(OPT_dynamic_list)) + for (auto *Arg : Args.filtered(OPT_dynamic_list)) { + Config->HasDynamicList = true; if (Optional Buffer = readFile(Arg->getValue())) readDynamicList(*Buffer); + } for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol)) Config->VersionScriptGlobals.push_back( Index: ELF/SymbolTable.h =================================================================== --- ELF/SymbolTable.h +++ ELF/SymbolTable.h @@ -91,8 +91,9 @@ void trace(StringRef Name); -private: std::vector findByVersion(SymbolVersion Ver); + +private: std::vector findAllByVersion(SymbolVersion Ver); llvm::StringMap> &getDemangledSyms(); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1182,8 +1182,18 @@ applySynthetic({In::EhFrame}, [](SyntheticSection *SS) { SS->finalizeContents(); }); - for (Symbol *S : Symtab->getSymbols()) - S->body()->IsPreemptible = S->body()->computeIsPreemptible(); + if (Config->HasDynamicList) { + for (SymbolVersion V : Config->VersionScriptGlobals) { + if (V.HasWildcard) + error("foo"); + std::vector Syms = Symtab->findByVersion(V); + for (SymbolBody *B : Syms) + B->IsPreemptible = true; + } + } else { + for (Symbol *S : Symtab->getSymbols()) + S->body()->IsPreemptible = S->body()->computeIsPreemptible(); + } // Scan relocations. This must be done after every symbol is declared so that // we can correctly decide if a dynamic relocation is needed. Index: test/ELF/dynamic-list-preempt.s =================================================================== --- /dev/null +++ test/ELF/dynamic-list-preempt.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "{ foo; };" > %t.list +# RUN: ld.lld -dynamic-list %t.list -shared %t.o -o %t.so +# RUN: llvm-readobj -r %t.so | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rela.plt { +# CHECK-NEXT: R_X86_64_JUMP_SLOT foo 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + + .globl foo +foo: + ret + + .globl bar +bar: + ret + + call foo@PLT + call bar@PLT