Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -61,3 +61,11 @@ def alias_entry : Separate<["-"], "e">, Alias; + +def no_allow_shlib_undefined + : Flag<["--"], "no-allow-shlib-undefined">, + HelpText<"This flag is ignored. --allow-shlib-undefined is always set">; + +def allow_shlib_undefined + : Flag<["--"], "allow-shlib-undefined">, + HelpText<"This flag is ignored. --allow-shlib-undefined is always set">; Index: ELF/Writer.h =================================================================== --- ELF/Writer.h +++ ELF/Writer.h @@ -10,6 +10,10 @@ #ifndef LLD_ELF_WRITER_H #define LLD_ELF_WRITER_H +namespace llvm { +class Twine; +} + namespace lld { namespace elf2 { @@ -18,6 +22,8 @@ template void writeResult(SymbolTable *Symtab); +void undefError(const llvm::Twine &Symbol, const llvm::Twine &SymFile); + } } Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -171,6 +171,20 @@ template void writeResult(SymbolTable *); template void writeResult(SymbolTable *); +void undefError(const Twine &Symbol, const Twine &SymFile) { + // DSO can contain unresolved symbols + if (Config->Shared) + return; + + std::string Message = Twine("undefined symbol: " + Symbol).str(); + if (!SymFile.isTriviallyEmpty()) + Message = Twine(Message.c_str() + Twine(" in ") + SymFile).str(); + if (Config->NoInhibitExec) + warning(Message); + else + error(Message); +} + } // namespace elf2 } // namespace lld @@ -281,13 +295,7 @@ SymFile = F.get(); } - std::string Message = "undefined symbol: " + Sym.getName().str(); - if (SymFile) - Message += " in " + SymFile->getName().str(); - if (Config->NoInhibitExec) - warning(Message); - else - error(Message); + undefError(Sym.getName(), SymFile ? SymFile->getName() : ""); } // Create output section objects and add them to OutputSections. Index: test/elf2/Inputs/allow-shlib-undefined.s =================================================================== --- test/elf2/Inputs/allow-shlib-undefined.s +++ test/elf2/Inputs/allow-shlib-undefined.s @@ -0,0 +1,3 @@ +.globl _shared +_shared: + call _unresolved Index: test/elf2/allow-shlib-undefined.s =================================================================== --- test/elf2/allow-shlib-undefined.s +++ test/elf2/allow-shlib-undefined.s @@ -0,0 +1,25 @@ +# --allow-shlib-undefined and --no-allow-shlib-undefined are fully +# ignored in linker implementation. +# --allow-shlib-undefined is set by default +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ +# RUN: %p/Inputs/allow-shlib-undefined.s -o %t +# RUN: lld -shared -flavor gnu2 %t -o %t.so +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 + +# Executable: should link with DSO containing undefined symbols in any case. +# RUN: lld -flavor gnu2 %t1 %t.so -o %t2 +# RUN: lld -flavor gnu2 --no-allow-shlib-undefined %t1 %t.so -o %t2 +# RUN: lld -flavor gnu2 --allow-shlib-undefined %t1 %t.so -o %t2 + +# DSO with undefines: +# should link with or without any of these options. +# RUN: lld -shared -flavor gnu2 %t -o %t.so +# RUN: lld -shared --allow-shlib-undefined -flavor gnu2 %t -o %t.so +# RUN: lld -shared --no-allow-shlib-undefined -flavor gnu2 %t -o %t.so + +# Executable still should not link when have undefines inside. +# RUN: not lld -flavor gnu2 %t -o %t.so + +.globl _start +_start: + call _shared