Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -77,6 +77,7 @@ bool ZNow; bool ZOrigin; bool ZRelro; + bool ExitEarly; ELFKind EKind = ELFNoneKind; uint16_t EMachine = llvm::ELF::EM_NONE; uint64_t EntryAddr = -1; Index: ELF/Driver.h =================================================================== --- ELF/Driver.h +++ ELF/Driver.h @@ -22,16 +22,17 @@ extern class LinkerDriver *Driver; // Entry point of the ELF linker. Returns true on success. -bool link(ArrayRef Args, llvm::raw_ostream &Error = llvm::errs()); +bool link(ArrayRef Args, bool CanExitEarly = false, + llvm::raw_ostream &Error = llvm::errs()); class LinkerDriver { public: - void main(ArrayRef Args); + void main(ArrayRef Args, bool CanExitEarly); void addFile(StringRef Path); void addLibrary(StringRef Name); private: - void readConfigs(llvm::opt::InputArgList &Args); + void readConfigs(llvm::opt::InputArgList &Args, bool CanExitEarly); void createFiles(llvm::opt::InputArgList &Args); template void link(llvm::opt::InputArgList &Args); Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -31,7 +31,8 @@ Configuration *elf2::Config; LinkerDriver *elf2::Driver; -bool elf2::link(ArrayRef Args, raw_ostream &Error) { +bool elf2::link(ArrayRef Args, bool CanExitEarly, + raw_ostream &Error) { HasError = false; ErrorOS = &Error; Configuration C; @@ -40,7 +41,7 @@ Config = &C; Driver = &D; Script = &LS; - Driver->main(Args.slice(1)); + Driver->main(Args.slice(1), CanExitEarly); return !HasError; } @@ -162,11 +163,11 @@ return false; } -void LinkerDriver::main(ArrayRef ArgsArr) { +void LinkerDriver::main(ArrayRef ArgsArr, bool CanExitEarly) { initSymbols(); opt::InputArgList Args = parseArgs(&Alloc, ArgsArr); - readConfigs(Args); + readConfigs(Args, CanExitEarly); createFiles(Args); checkOptions(Args); if (HasError) @@ -191,7 +192,7 @@ } // Initializes Config members by the command line options. -void LinkerDriver::readConfigs(opt::InputArgList &Args) { +void LinkerDriver::readConfigs(opt::InputArgList &Args, bool CanExitEarly) { for (auto *Arg : Args.filtered(OPT_L)) Config->SearchPaths.push_back(Arg->getValue()); @@ -225,6 +226,7 @@ Config->Shared = Args.hasArg(OPT_shared); Config->StripAll = Args.hasArg(OPT_strip_all); Config->Verbose = Args.hasArg(OPT_verbose); + Config->ExitEarly = CanExitEarly && !Args.hasArg(OPT_full_shutdown); Config->DynamicLinker = getString(Args, OPT_dynamic_linker); Config->Entry = getString(Args, OPT_entry); Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -54,6 +54,8 @@ def fini : Separate<["-"], "fini">, MetaVarName<"">, HelpText<"Specify a finalizer function">; +def full_shutdown : Flag<["--"], "full-shutdown">, HelpText<"foobar">; + def hash_style : Separate<["--", "-"], "hash-style">, HelpText<"Specify hash style (sysv, gnu or both)">; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -21,6 +21,10 @@ #include "llvm/Support/StringSaver.h" #include "llvm/Support/raw_ostream.h" +#if !defined(_MSC_VER) && !defined(__MINGW32__) +#include +#endif + using namespace llvm; using namespace llvm::ELF; using namespace llvm::object; @@ -203,6 +207,8 @@ if (HasError) return; fatal(Buffer->commit()); + if (Config->ExitEarly) + _exit(0); } namespace { Index: include/lld/Driver/Driver.h =================================================================== --- include/lld/Driver/Driver.h +++ include/lld/Driver/Driver.h @@ -125,7 +125,8 @@ } namespace elf2 { -bool link(llvm::ArrayRef args, raw_ostream &diag = llvm::errs()); +bool link(llvm::ArrayRef args, bool CanExitEarly = false, + raw_ostream &diag = llvm::errs()); } /// Driver for lld unit tests Index: lib/Driver/UniversalDriver.cpp =================================================================== --- lib/Driver/UniversalDriver.cpp +++ lib/Driver/UniversalDriver.cpp @@ -205,7 +205,7 @@ case Flavor::old_gnu_ld: return GnuLdDriver::linkELF(args, diagnostics); case Flavor::gnu_ld: - return elf2::link(args, diagnostics); + return elf2::link(args, true, diagnostics); case Flavor::darwin_ld: return DarwinLdDriver::linkMachO(args, diagnostics); case Flavor::win_link: