[ELF] - Recommit r309252 "[ELF] - Fix missing relocation when linking executable...
authorGeorge Rimar <grimar@accesssoftek.com>
Wed, 2 Aug 2017 07:51:08 +0000 (07:51 +0000)
committerGeorge Rimar <grimar@accesssoftek.com>
Wed, 2 Aug 2017 07:51:08 +0000 (07:51 +0000)
With fix for undefined weak symbols in executable.

Original commit message:
This is PR32112. Previously when we linked executable with
--unresolved-symbols=ignore-all and undefined symbols, like:

_start:
callq und@PLT

we did not create relocations, though it looks in that case
we should delegate handling of such symbols to runtime linker,
hence should emit them. Patch fixes that.

Differential revision: https://reviews.llvm.org/D35724

llvm-svn: 309796

lld/ELF/Symbols.cpp
lld/test/ELF/executable-undefined-ignoreall.s [new file with mode: 0644]
lld/test/ELF/executable-undefined-protected-ignoreall.s [new file with mode: 0644]
lld/test/ELF/no-inhibit-exec.s

index d3f6cc6..61032a6 100644 (file)
@@ -141,10 +141,6 @@ bool SymbolBody::isPreemptible() const {
   if (isShared())
     return !NeedsCopy && !NeedsPltAddr;
 
-  // That's all that can be preempted in a non-DSO.
-  if (!Config->Shared)
-    return false;
-
   // Only symbols that appear in dynsym can be preempted.
   if (!symbol()->includeInDynsym())
     return false;
@@ -153,6 +149,15 @@ bool SymbolBody::isPreemptible() const {
   if (symbol()->Visibility != STV_DEFAULT)
     return false;
 
+  // Undefined symbols in non-DSOs are usually just an error, so it
+  // doesn't matter whether we return true or false here. However, if
+  // -unresolved-symbols=ignore-all is specified, undefined symbols in
+  // executables are automatically exported so that the runtime linker
+  // can try to resolve them. In that case, they is preemptible. So, we
+  // return true for an undefined symbol in case the option is specified.
+  if (!Config->Shared)
+    return isUndefined();
+
   // -Bsymbolic means that definitions are not preempted.
   if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))
     return !isDefined();
@@ -358,7 +363,7 @@ bool Symbol::includeInDynsym() const {
   if (computeBinding() == STB_LOCAL)
     return false;
   if (body()->isUndefined())
-    return Config->Shared;
+    return Config->Shared || !body()->symbol()->isWeak();
   return ExportDynamic || body()->isShared();
 }
 
diff --git a/lld/test/ELF/executable-undefined-ignoreall.s b/lld/test/ELF/executable-undefined-ignoreall.s
new file mode 100644 (file)
index 0000000..44f83a6
--- /dev/null
@@ -0,0 +1,13 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %tout --unresolved-symbols=ignore-all -pie
+# RUN: llvm-readobj -r %tout | FileCheck %s
+
+# CHECK:      Relocations [
+# CHECK-NEXT:   Section ({{.*}}) .rela.plt {
+# CHECK-NEXT:     0x2018 R_X86_64_JUMP_SLOT foo 0x0
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+_start:
+callq foo@PLT
diff --git a/lld/test/ELF/executable-undefined-protected-ignoreall.s b/lld/test/ELF/executable-undefined-protected-ignoreall.s
new file mode 100644 (file)
index 0000000..3791179
--- /dev/null
@@ -0,0 +1,8 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: not ld.lld %t -o %tout --unresolved-symbols=ignore-all -pie 2>&1 | FileCheck %s
+# CHECK: error: undefined symbol: foo
+
+.protected foo
+_start:
+callq foo@PLT
index d0970d9..ad60f1c 100644 (file)
@@ -2,11 +2,15 @@
 # RUN: not ld.lld %t -o %t2
 # RUN: ld.lld %t --noinhibit-exec -o %t2
 # RUN: llvm-objdump -d %t2 | FileCheck %s
+# RUN: llvm-readobj -r %t2 | FileCheck %s --check-prefix=RELOC
 # REQUIRES: x86
 
 # CHECK: Disassembly of section .text:
 # CHECK-NEXT: _start
-# CHECK-NEXT: 201000: {{.*}} callq -2101253
+# CHECK-NEXT: 201000: {{.*}} callq 0
+
+# RELOC:      Relocations [
+# RELOC-NEXT: ]
 
 # next code will not link without noinhibit-exec flag
 # because of undefined symbol _bar