[llvm-branch-commits] [lld] cc1cf63 - [lld-macho] Implement option: -undefined TREATMENT

Greg McGary via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Dec 17 17:54:45 PST 2020


Author: Greg McGary
Date: 2020-12-17T17:40:50-08:00
New Revision: cc1cf6332a301331ef1b20e24948159dc291014a

URL: https://github.com/llvm/llvm-project/commit/cc1cf6332a301331ef1b20e24948159dc291014a
DIFF: https://github.com/llvm/llvm-project/commit/cc1cf6332a301331ef1b20e24948159dc291014a.diff

LOG: [lld-macho] Implement option: -undefined TREATMENT

TREATMENT can be `error`, `warning`, `suppress`, or `dynamic_lookup`
The `dymanic_lookup` remains unimplemented for now.

Differential Revision: https://reviews.llvm.org/D93263

Added: 
    lld/test/MachO/treat-undef-sym.s

Modified: 
    lld/MachO/Config.h
    lld/MachO/Driver.cpp
    lld/MachO/Options.td
    lld/MachO/SymbolTable.cpp
    lld/MachO/SymbolTable.h
    lld/MachO/Writer.cpp
    lld/test/MachO/demangle.s
    lld/test/MachO/invalid/stub-link.s
    lld/test/MachO/invalid/undefined-symbol.s
    lld/test/MachO/weak-reference.s

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index 029b9ab2296c..4f27ec2db45f 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -30,6 +30,14 @@ struct PlatformInfo {
   llvm::VersionTuple sdk;
 };
 
+enum class UndefinedSymbolTreatment {
+  unknown,
+  error,
+  warning,
+  suppress,
+  dynamic_lookup,
+};
+
 struct Configuration {
   Symbol *entry;
   bool hasReexports = false;
@@ -52,6 +60,8 @@ struct Configuration {
   bool demangle = false;
   llvm::MachO::Architecture arch;
   PlatformInfo platform;
+  UndefinedSymbolTreatment undefinedSymbolTreatment =
+      UndefinedSymbolTreatment::error;
   llvm::MachO::HeaderFileType outputType;
   std::vector<llvm::StringRef> systemLibraryRoots;
   std::vector<llvm::StringRef> librarySearchPaths;

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 4f9c111bd8fb..63d101270cf5 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -599,6 +599,22 @@ static void handlePlatformVersion(const opt::Arg *arg) {
     error(Twine("malformed sdk version: ") + sdkVersionStr);
 }
 
+static void handleUndefined(const opt::Arg *arg) {
+  StringRef treatmentStr = arg->getValue(0);
+  config->undefinedSymbolTreatment =
+      llvm::StringSwitch<UndefinedSymbolTreatment>(treatmentStr)
+          .Case("error", UndefinedSymbolTreatment::error)
+          .Case("warning", UndefinedSymbolTreatment::warning)
+          .Case("suppress", UndefinedSymbolTreatment::suppress)
+          .Case("dynamic_lookup", UndefinedSymbolTreatment::dynamic_lookup)
+          .Default(UndefinedSymbolTreatment::unknown);
+  if (config->undefinedSymbolTreatment == UndefinedSymbolTreatment::unknown) {
+    warn(Twine("unknown -undefined TREATMENT '") + treatmentStr +
+         "', defaulting to 'error'");
+    config->undefinedSymbolTreatment = UndefinedSymbolTreatment::error;
+  }
+}
+
 static void warnIfDeprecatedOption(const opt::Option &opt) {
   if (!opt.getGroup().isValid())
     return;
@@ -809,6 +825,9 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
     case OPT_platform_version:
       handlePlatformVersion(arg);
       break;
+    case OPT_undefined:
+      handleUndefined(arg);
+      break;
     default:
       break;
     }

diff  --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index e3ee14a74328..1ab2f9109ee0 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -408,7 +408,6 @@ def U : Separate<["-"], "U">,
 def undefined : Separate<["-"], "undefined">,
      MetaVarName<"<treatment>">,
      HelpText<"Handle undefined symbols according to <treatment>: error, warning, suppress, or dynamic_lookup (default is error)">,
-     Flags<[HelpHidden]>,
      Group<grp_resolve>;
 def rpath : Separate<["-"], "rpath">,
      MetaVarName<"<path>">,

diff  --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp
index 93a2508951a5..ea231c9786e2 100644
--- a/lld/MachO/SymbolTable.cpp
+++ b/lld/MachO/SymbolTable.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "SymbolTable.h"
+#include "Config.h"
 #include "InputFiles.h"
 #include "Symbols.h"
 #include "lld/Common/ErrorHandler.h"
@@ -154,4 +155,26 @@ Symbol *SymbolTable::addDSOHandle(const MachHeaderSection *header) {
   return s;
 }
 
+void lld::macho::treatUndefinedSymbol(StringRef symbolName,
+                                      StringRef fileName) {
+  std::string message = ("undefined symbol: " + symbolName).str();
+  if (!fileName.empty())
+    message += ("\n>>> referenced by " + fileName).str();
+  switch (config->undefinedSymbolTreatment) {
+  case UndefinedSymbolTreatment::suppress:
+    break;
+  case UndefinedSymbolTreatment::error:
+    error(message);
+    break;
+  case UndefinedSymbolTreatment::warning:
+    warn(message);
+    break;
+  case UndefinedSymbolTreatment::dynamic_lookup:
+    error("dynamic_lookup unimplemented for " + message);
+    break;
+  case UndefinedSymbolTreatment::unknown:
+    llvm_unreachable("unknown -undefined TREATMENT");
+  }
+}
+
 SymbolTable *macho::symtab;

diff  --git a/lld/MachO/SymbolTable.h b/lld/MachO/SymbolTable.h
index fbf36619983c..89c866594d72 100644
--- a/lld/MachO/SymbolTable.h
+++ b/lld/MachO/SymbolTable.h
@@ -55,6 +55,8 @@ class SymbolTable {
   std::vector<Symbol *> symVector;
 };
 
+extern void treatUndefinedSymbol(StringRef symbolName, StringRef fileName);
+
 extern SymbolTable *symtab;
 
 } // namespace macho

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index a4c677a4b288..fbd03f80157d 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -412,8 +412,7 @@ void Writer::scanRelocations() {
     for (Reloc &r : isec->relocs) {
       if (auto *s = r.referent.dyn_cast<lld::macho::Symbol *>()) {
         if (isa<Undefined>(s))
-          error("undefined symbol " + toString(*s) + ", referenced from " +
-                toString(isec->file));
+          treatUndefinedSymbol(toString(*s), toString(isec->file));
         else
           target->prepareSymbolRelocation(s, isec, r);
       } else {

diff  --git a/lld/test/MachO/demangle.s b/lld/test/MachO/demangle.s
index c3ff999a468d..0352f16210ba 100644
--- a/lld/test/MachO/demangle.s
+++ b/lld/test/MachO/demangle.s
@@ -6,8 +6,8 @@
 # RUN: not %lld -demangle %t.o -o /dev/null 2>&1 | \
 # RUN:     FileCheck --check-prefix=DEMANGLE %s
 
-# CHECK: undefined symbol __Z1fv
-# DEMANGLE: undefined symbol f()
+# CHECK: undefined symbol: __Z1fv
+# DEMANGLE: undefined symbol: f()
 
 .globl _main
 _main:

diff  --git a/lld/test/MachO/invalid/stub-link.s b/lld/test/MachO/invalid/stub-link.s
index fe7f0e153143..486773244dab 100644
--- a/lld/test/MachO/invalid/stub-link.s
+++ b/lld/test/MachO/invalid/stub-link.s
@@ -8,8 +8,8 @@
 # RUN: llvm-mc -filetype obj -triple x86_64-apple-ios %s -o %t/test.o
 # RUN: not lld -flavor darwinnew -o %t/test -syslibroot %S/../Inputs/iPhoneSimulator.sdk -lSystem %t/test.o 2>&1 | FileCheck %s
 
-# CHECK-DAG: error: undefined symbol __cache_handle_memory_pressure_event
-# CHECK-DAG: error: undefined symbol _from_non_reexported_tapi_dylib
+# CHECK-DAG: error: undefined symbol: __cache_handle_memory_pressure_event
+# CHECK-DAG: error: undefined symbol: _from_non_reexported_tapi_dylib
 
 .section __TEXT,__text
 .global _main

diff  --git a/lld/test/MachO/invalid/undefined-symbol.s b/lld/test/MachO/invalid/undefined-symbol.s
index a1cc07f37553..7dffe47f68e3 100644
--- a/lld/test/MachO/invalid/undefined-symbol.s
+++ b/lld/test/MachO/invalid/undefined-symbol.s
@@ -10,7 +10,8 @@
 # RUN:     FileCheck %s -DSYM=_bar -DFILENAME='foo.a(foo.o)'
 # RUN: not %lld -o /dev/null %t/main.o -force_load %t/foo.a 2>&1 | \
 # RUN:     FileCheck %s -DSYM=_bar -DFILENAME='foo.a(foo.o)'
-# CHECK: error: undefined symbol [[SYM]], referenced from [[FILENAME]]
+# CHECK: error: undefined symbol: [[SYM]]
+# CHECK-NEXT: >>> referenced by [[FILENAME]]
 
 #--- foo.s
 .globl _foo

diff  --git a/lld/test/MachO/treat-undef-sym.s b/lld/test/MachO/treat-undef-sym.s
new file mode 100644
index 000000000000..3628c30c8250
--- /dev/null
+++ b/lld/test/MachO/treat-undef-sym.s
@@ -0,0 +1,28 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos %s -o %t.o
+# RUN: not %lld -undefined bogus -o /dev/null %t.o 2>&1 | \
+# RUN:     FileCheck %s -check-prefix=UNKNOWN
+# RUN: not %lld -undefined error -o /dev/null %t.o 2>&1 | \
+# RUN:     FileCheck %s -check-prefix=ERROR
+# RUN:     %no_fatal_warnings_lld -undefined warning -o /dev/null %t.o 2>&1 | \
+# RUN:     FileCheck %s -check-prefix=WARNING
+# RUN:     %lld -undefined suppress -o /dev/null %t.o 2>&1 | \
+# RUN:     FileCheck %s -check-prefix=SUPPRESS --allow-empty
+
+# ERROR: error: undefined symbol: _bar
+# ERROR-NEXT: >>> referenced by
+
+# WARNING: warning: undefined symbol: _bar
+# WARNING-NEXT: >>> referenced by
+
+# SUPPRESS-NOT: undefined symbol: _bar
+
+# UNKNOWN: unknown -undefined TREATMENT 'bogus'
+# UNKNOWN-NEXT: error: undefined symbol: _bar
+# UNKNOWN-NEXT: >>> referenced by
+
+.globl _main
+_main:
+  callq _bar
+  ret

diff  --git a/lld/test/MachO/weak-reference.s b/lld/test/MachO/weak-reference.s
index a95002b141a0..6b6c29753d11 100644
--- a/lld/test/MachO/weak-reference.s
+++ b/lld/test/MachO/weak-reference.s
@@ -94,7 +94,7 @@
 ## Weak references must still be satisfied at link time.
 # RUN: not %lld -lSystem %t/invalid.o -o /dev/null 2>&1 | FileCheck %s \
 # RUN:   --check-prefix=INVALID -DDIR=%t
-# INVALID: error: undefined symbol _missing, referenced from [[DIR]]/invalid.o
+# INVALID: error: undefined symbol: _missing
 
 #--- libfoo.s
 .globl _foo, _foo_fn, _weak_foo, _weak_foo_fn


        


More information about the llvm-branch-commits mailing list