[lld] r309252 - [ELF] - Fix missing relocation when linking executable with --unresolved-symbols=ignore-all

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 27 00:31:31 PDT 2017


Author: grimar
Date: Thu Jul 27 00:31:31 2017
New Revision: 309252

URL: http://llvm.org/viewvc/llvm-project?rev=309252&view=rev
Log:
[ELF] - Fix missing relocation when linking executable with --unresolved-symbols=ignore-all

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

_start:
callq und at 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

Added:
    lld/trunk/test/ELF/executable-undefined-ignoreall.s
    lld/trunk/test/ELF/executable-undefined-protected-ignoreall.s
Modified:
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/test/ELF/no-inhibit-exec.s

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=309252&r1=309251&r2=309252&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Thu Jul 27 00:31:31 2017
@@ -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();
@@ -357,8 +362,11 @@ uint8_t Symbol::computeBinding() const {
 bool Symbol::includeInDynsym() const {
   if (computeBinding() == STB_LOCAL)
     return false;
-  return ExportDynamic || body()->isShared() ||
-         (body()->isUndefined() && Config->Shared);
+  if (ExportDynamic || body()->isShared())
+    return true;
+  if (!body()->isUndefined())
+    return false;
+  return Config->Shared || !body()->symbol()->isWeak();
 }
 
 // Print out a log message for --trace-symbol.

Added: lld/trunk/test/ELF/executable-undefined-ignoreall.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/executable-undefined-ignoreall.s?rev=309252&view=auto
==============================================================================
--- lld/trunk/test/ELF/executable-undefined-ignoreall.s (added)
+++ lld/trunk/test/ELF/executable-undefined-ignoreall.s Thu Jul 27 00:31:31 2017
@@ -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 at PLT

Added: lld/trunk/test/ELF/executable-undefined-protected-ignoreall.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/executable-undefined-protected-ignoreall.s?rev=309252&view=auto
==============================================================================
--- lld/trunk/test/ELF/executable-undefined-protected-ignoreall.s (added)
+++ lld/trunk/test/ELF/executable-undefined-protected-ignoreall.s Thu Jul 27 00:31:31 2017
@@ -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 at PLT

Modified: lld/trunk/test/ELF/no-inhibit-exec.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/no-inhibit-exec.s?rev=309252&r1=309251&r2=309252&view=diff
==============================================================================
--- lld/trunk/test/ELF/no-inhibit-exec.s (original)
+++ lld/trunk/test/ELF/no-inhibit-exec.s Thu Jul 27 00:31:31 2017
@@ -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 code will not link without noinhibit-exec flag
 # because of undefined symbol _bar




More information about the llvm-commits mailing list