Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -30,6 +30,7 @@ bool DiscardNone; bool ExportDynamic; bool NoInhibitExec; + bool NoUndefined; bool Shared; bool Static = false; }; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -123,6 +123,7 @@ Config->DiscardNone = Args.hasArg(OPT_discard_none); Config->ExportDynamic = Args.hasArg(OPT_export_dynamic); Config->NoInhibitExec = Args.hasArg(OPT_noinhibit_exec); + Config->NoUndefined = Args.hasArg(OPT_no_undefined); Config->Shared = Args.hasArg(OPT_shared); for (auto *Arg : Args) { Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -36,6 +36,9 @@ def noinhibit_exec : Flag<["--"], "noinhibit-exec">, HelpText<"Retain the executable output file whenever it is still usable">; +def no_undefined : Flag<["--"], "no-undefined">, + HelpText<"Report unresolved symbols even if the linker is creating a shared library">; + def output : Separate<["-"], "o">, MetaVarName<"">, HelpText<"Path to file to write output">; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -271,7 +271,7 @@ typedef typename ELFFile::Elf_Sym Elf_Sym; typedef typename ELFFile::Elf_Sym_Range Elf_Sym_Range; - if (Config->Shared) + if (Config->Shared && !Config->NoUndefined) return; const Elf_Sym &SymE = cast>(Sym).Sym; Index: test/elf2/no-undefined.s =================================================================== --- test/elf2/no-undefined.s +++ test/elf2/no-undefined.s @@ -0,0 +1,7 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: not lld --no-undefined -shared -flavor gnu2 %t -o %t.so +# RUN: lld -shared -flavor gnu2 %t -o %t1.so + +.globl _shared +_shared: + call _unresolved