[PATCH] D77280: [ELF] Make --version-script work for lazy symbols fetched by LTO libcalls

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 1 17:27:09 PDT 2020


MaskRay created this revision.
MaskRay added reviewers: grimar, phosek, ruiu.
Herald added subscribers: llvm-commits, dexonsmith, steven_wu, hiraditya, arichardson, inglorion, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.

Fixes https://bugs.llvm.org//show_bug.cgi?id=45391

The LTO code generator happens after version script scanning and may
create references which will fetch some lazy symbols.

Currently a version script does not assign VER_NDX_LOCAL to lazy symbols
and such symbols will be made global after they are fetched.

Change findByVersion and findAllByVersion to work on lazy symbols.
For unfetched lazy symbols, we should keep them non-local (D35263 <https://reviews.llvm.org/D35263>).
Check isDefined() in computeBinding() as a compensation.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77280

Files:
  lld/ELF/SymbolTable.cpp
  lld/ELF/Symbols.cpp
  lld/test/ELF/lto/version-libcall.ll


Index: lld/test/ELF/lto/version-libcall.ll
===================================================================
--- /dev/null
+++ 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
+}
Index: lld/ELF/Symbols.cpp
===================================================================
--- lld/ELF/Symbols.cpp
+++ 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;
Index: lld/ELF/SymbolTable.cpp
===================================================================
--- lld/ELF/SymbolTable.cpp
+++ 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;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D77280.254371.patch
Type: text/x-patch
Size: 2907 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200402/560d88e4/attachment.bin>


More information about the llvm-commits mailing list