[PATCH] D35724: [ELF] - Fix missing relocation when linking executable with --unresolved-symbols=ignore-all

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 25 02:42:17 PDT 2017


grimar updated this revision to Diff 108026.
grimar added a comment.

- Removed --noinhibit-exec relative code. It was splitted to https://reviews.llvm.org/D35793.

Notes: without https://reviews.llvm.org/D35793 this fails 2 testcases currently.


https://reviews.llvm.org/D35724

Files:
  ELF/Relocations.cpp
  ELF/Symbols.cpp
  ELF/Symbols.h
  test/ELF/executable-undefined-ignoreall.s


Index: test/ELF/executable-undefined-ignoreall.s
===================================================================
--- test/ELF/executable-undefined-ignoreall.s
+++ test/ELF/executable-undefined-ignoreall.s
@@ -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
Index: ELF/Symbols.h
===================================================================
--- ELF/Symbols.h
+++ ELF/Symbols.h
@@ -369,6 +369,7 @@
   unsigned InVersionScript : 1;
 
   bool includeInDynsym() const;
+  bool canBeExternal() const;
   uint8_t computeBinding() const;
   bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
 
Index: ELF/Symbols.cpp
===================================================================
--- ELF/Symbols.cpp
+++ ELF/Symbols.cpp
@@ -141,18 +141,20 @@
   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;
 
   // Only default visibility symbols can be preempted.
   if (symbol()->Visibility != STV_DEFAULT)
     return false;
 
+  // Undefined external symbols in a non-DSO usually reported by linker and link
+  // fails, but together with --unresolved-symbols=ignore-all link succeeds and
+  // runtime linker should take care about them during execution.
+  if (!Config->Shared)
+    return isUndefined();
+
   // -Bsymbolic means that definitions are not preempted.
   if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))
     return !isDefined();
@@ -354,11 +356,21 @@
   return Binding;
 }
 
+bool Symbol::canBeExternal() const {
+  return computeBinding() != STB_LOCAL &&
+         body()->getVisibility() == STV_DEFAULT;
+}
+
 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;
+  if (Config->Shared)
+    return true;
+  return canBeExternal() && !body()->symbol()->isWeak();
 }
 
 // Print out a log message for --trace-symbol.
Index: ELF/Relocations.cpp
===================================================================
--- ELF/Relocations.cpp
+++ ELF/Relocations.cpp
@@ -678,8 +678,7 @@
   if (Config->UnresolvedSymbols == UnresolvedPolicy::IgnoreAll)
     return;
 
-  bool CanBeExternal = Sym.symbol()->computeBinding() != STB_LOCAL &&
-                       Sym.getVisibility() == STV_DEFAULT;
+  bool CanBeExternal = Sym.symbol()->canBeExternal();
   if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal)
     return;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D35724.108026.patch
Type: text/x-patch
Size: 3116 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170725/9e7a1072/attachment.bin>


More information about the llvm-commits mailing list