[ELF] Fix includeInDynsym() when an undefined weak is merged with a lazy definition
authorFangrui Song <maskray@google.com>
Thu, 9 Jan 2020 23:53:52 +0000 (15:53 -0800)
committerFangrui Song <maskray@google.com>
Fri, 10 Jan 2020 00:24:02 +0000 (16:24 -0800)
An undefined weak does not fetch the lazy definition. A lazy weak symbol
should be considered undefined, and thus preemptible if .dynsym exists.

D71795 is not quite an NFC. It errors on an R_X86_64_PLT32 referencing
an undefined weak symbol. isPreemptible is false (incorrect) => R_PLT_PC
is optimized to R_PC => in isStaticLinkTimeConstant, an error is emitted
when an R_PC is applied on an undefined weak (considered absolute).

lld/ELF/Symbols.cpp
lld/test/ELF/weak-undef-lib.s

index a9e3645..f0f6121 100644 (file)
@@ -277,8 +277,10 @@ bool Symbol::includeInDynsym() const {
     return false;
   if (computeBinding() == STB_LOCAL)
     return false;
+  if (!isDefined() && !isCommon())
+    return true;
 
-  return isUndefined() || isShared() || exportDynamic || inDynamicList;
+  return exportDynamic || inDynamicList;
 }
 
 // Print out a log message for --trace-symbol.
index 0b4183e..54e05dc 100644 (file)
@@ -6,6 +6,9 @@
 # RUN: ld.lld -shared -o %t.so %t1.o --start-lib %t2.o
 # RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s
 
+# RUN: ld.lld -pie -o %t %t1.o --start-lib %t2.o
+# RUN: llvm-readobj --dyn-syms %t | FileCheck %s
+
 # CHECK:      Name: foo
 # CHECK-NEXT: Value: 0x0
 # CHECK-NEXT: Size: 0
@@ -15,5 +18,7 @@
 # CHECK-NEXT: Section: Undefined
 
 .weak foo
+call foo@PLT
+
 .data
 .quad foo