[lld] r293290 - Fix and simplify the reporting of undefined symbols.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 27 07:52:09 PST 2017


Author: rafael
Date: Fri Jan 27 09:52:08 2017
New Revision: 293290

URL: http://llvm.org/viewvc/llvm-project?rev=293290&view=rev
Log:
Fix and simplify the reporting of undefined symbols.

Now reportUndefined only has to look at Config->UnresolvedSymbols and
the symbol. getUnresolvedSymbolOption does all the hard work of
mapping options like -shared and -z defs to one of the
UnresolvedPolicy enum entries.

The critical fix is that now "-z defs --warn-unresolved-symbols" only
warns.

Added:
    lld/trunk/test/ELF/warn-unresolved-symbols-hidden.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Relocations.cpp

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=293290&r1=293289&r2=293290&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Fri Jan 27 09:52:08 2017
@@ -41,7 +41,7 @@ enum class DiscardPolicy { Default, All,
 enum class StripPolicy { None, All, Debug };
 
 // For --unresolved-symbols.
-enum class UnresolvedPolicy { NoUndef, ReportError, Warn, Ignore };
+enum class UnresolvedPolicy { ReportError, Warn, WarnAll, Ignore, IgnoreAll };
 
 // For --sort-section and linkerscript sorting rules.
 enum class SortSectionPolicy { Default, None, Alignment, Name, Priority };

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=293290&r1=293289&r2=293290&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Fri Jan 27 09:52:08 2017
@@ -350,29 +350,39 @@ void LinkerDriver::main(ArrayRef<const c
 }
 
 static UnresolvedPolicy getUnresolvedSymbolOption(opt::InputArgList &Args) {
+  // Find the last of --unresolved-symbols, --no-undefined and -z defs.
+  bool UnresolvedSymbolIsIgnoreAll = false;
+  bool ZDefs = false;
+  for (auto *Arg : Args) {
+    unsigned ID = Arg->getOption().getID();
+    if (ID == OPT_unresolved_symbols) {
+      StringRef S = Arg->getValue();
+      if (S == "ignore-all" || S == "ignore-in-object-files") {
+        ZDefs = false;
+        UnresolvedSymbolIsIgnoreAll = true;
+      } else if (S != "ignore-in-shared-libs" && S != "report-all") {
+        error("unknown --unresolved-symbols value: " + S);
+      }
+    } else if (ID == OPT_no_undefined ||
+               (ID == OPT_z && Arg->getValue() == StringRef("defs"))) {
+      ZDefs = true;
+      UnresolvedSymbolIsIgnoreAll = false;
+    }
+  }
+
   if (Args.hasArg(OPT_noinhibit_exec))
-    return UnresolvedPolicy::Warn;
-  if (Args.hasArg(OPT_no_undefined) || hasZOption(Args, "defs"))
-    return UnresolvedPolicy::NoUndef;
+    return UnresolvedPolicy::WarnAll;
   if (Config->Relocatable)
-    return UnresolvedPolicy::Ignore;
-
-  if (auto *Arg = Args.getLastArg(OPT_warn_undef, OPT_error_undef)) {
-    if (Arg->getOption().getID() == OPT_warn_undef)
-      return UnresolvedPolicy::Warn;
+    return UnresolvedPolicy::IgnoreAll;
 
+  if (ZDefs || (!Config->Shared && !UnresolvedSymbolIsIgnoreAll)) {
+    if (auto *Arg = Args.getLastArg(OPT_warn_undef, OPT_error_undef))
+      if (Arg->getOption().getID() == OPT_warn_undef)
+        return UnresolvedPolicy::Warn;
     return UnresolvedPolicy::ReportError;
   }
 
-  if (auto *Arg = Args.getLastArg(OPT_unresolved_symbols)) {
-    StringRef S = Arg->getValue();
-    if (S == "ignore-all" || S == "ignore-in-object-files")
-      return UnresolvedPolicy::Ignore;
-    if (S == "ignore-in-shared-libs" || S == "report-all")
-      return UnresolvedPolicy::ReportError;
-    error("unknown --unresolved-symbols value: " + S);
-  }
-  return UnresolvedPolicy::ReportError;
+  return UnresolvedPolicy::Ignore;
 }
 
 static Target2Policy getTarget2Option(opt::InputArgList &Args) {

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=293290&r1=293289&r2=293290&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Fri Jan 27 09:52:08 2017
@@ -555,17 +555,17 @@ static typename ELFT::uint computeAddend
 template <class ELFT>
 static void reportUndefined(SymbolBody &Sym, InputSectionBase<ELFT> &S,
                             typename ELFT::uint Offset) {
-  if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore)
-    return;
-
-  if (Config->Shared && Sym.symbol()->Visibility == STV_DEFAULT &&
-      Config->UnresolvedSymbols != UnresolvedPolicy::NoUndef)
+  bool CanBeExternal = Sym.symbol()->computeBinding() != STB_LOCAL &&
+                       Sym.getVisibility() == STV_DEFAULT;
+  if (Config->UnresolvedSymbols == UnresolvedPolicy::IgnoreAll ||
+      (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal))
     return;
 
   std::string Msg =
       S.getLocation(Offset) + ": undefined symbol '" + toString(Sym) + "'";
 
-  if (Config->UnresolvedSymbols == UnresolvedPolicy::Warn)
+  if (Config->UnresolvedSymbols == UnresolvedPolicy::WarnAll ||
+      (Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal))
     warn(Msg);
   else
     error(Msg);

Added: lld/trunk/test/ELF/warn-unresolved-symbols-hidden.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/warn-unresolved-symbols-hidden.s?rev=293290&view=auto
==============================================================================
--- lld/trunk/test/ELF/warn-unresolved-symbols-hidden.s (added)
+++ lld/trunk/test/ELF/warn-unresolved-symbols-hidden.s Fri Jan 27 09:52:08 2017
@@ -0,0 +1,14 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: not ld.lld -shared %t.o -o %t.so -z defs --warn-unresolved-symbols 2>&1| FileCheck %s
+
+# CHECK: warning: {{.*}}: undefined symbol 'foo'
+# CHECK: error: {{.*}}: undefined symbol 'bar'
+# CHECK: error: {{.*}}: undefined symbol 'zed'
+
+        .data
+        .quad foo
+        .hidden bar
+        .quad bar
+        .protected zed
+        .quad zed




More information about the llvm-commits mailing list