diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -120,7 +120,7 @@ if (!demangledSyms) { demangledSyms.emplace(); for (Symbol *sym : symVector) { - if (!sym->isDefined() && !sym->isCommon()) + if (!sym->isDefined() && !sym->isCommon() && !sym->isLazy()) continue; (*demangledSyms)[demangleItanium(sym->getName())].push_back(sym); } @@ -132,7 +132,7 @@ if (ver.isExternCpp) return getDemangledSyms().lookup(ver.name); if (Symbol *b = find(ver.name)) - if (b->isDefined() || b->isCommon()) + if (b->isDefined() || b->isCommon() || b->isLazy()) return {b}; return {}; } @@ -149,7 +149,8 @@ } for (Symbol *sym : symVector) - if ((sym->isDefined() || sym->isCommon()) && m.match(sym->getName())) + if ((sym->isDefined() || sym->isCommon() || sym->isLazy()) && + m.match(sym->getName())) res.push_back(sym); return res; } diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -276,7 +276,7 @@ if (config->relocatable) return binding; if ((visibility != STV_DEFAULT && visibility != STV_PROTECTED) || - versionId == VER_NDX_LOCAL) + (versionId == VER_NDX_LOCAL && isDefined())) return STB_LOCAL; if (!config->gnuUnique && binding == STB_GNU_UNIQUE) return STB_GLOBAL; diff --git a/lld/test/ELF/lto/version-libcall.ll b/lld/test/ELF/lto/version-libcall.ll new file mode 100644 --- /dev/null +++ b/lld/test/ELF/lto/version-libcall.ll @@ -0,0 +1,29 @@ +; REQUIRES: x86 +;; The LTO code generator may create references which will fetch lazy symbols. +;; Test that version script local: directives can change the binding of such +;; symbols to STB_LOCAL. This is a bit complex because the LTO code generator +;; happens after version script scanning and can change symbols from Lazy to Defined. + +; RUN: llvm-as %s -o %t.bc +; RUN: echo '.globl __udivti3; __udivti3:' | llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o + +; RUN: echo '{ global: foo; local: *; };' > %t.wild.ver +; RUN: ld.lld -shared --version-script %t.wild.ver %t.bc --start-lib %t1.o --end-lib -o %t.wild.so +; RUN: llvm-nm %t.wild.so | FileCheck %s + +; RUN: echo '{ global: foo; local: __udivti3; };' > %t.exact.ver +; RUN: ld.lld -shared --version-script %t.exact.ver %t.bc --start-lib %t1.o --end-lib -o %t.exact.so +; RUN: llvm-nm %t.exact.so | FileCheck %s + +; CHECK: t __udivti3 +; CHECK: T foo + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare i64 @llvm.udiv.fix.i64(i64, i64, i32) + +define i64 @foo(i64 %x, i64 %y) { + %ret = call i64 @llvm.udiv.fix.i64(i64 %x, i64 %y, i32 31) + ret i64 %ret +}