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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits