diff options
-rw-r--r-- | lld/ELF/Config.h | 1 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 8 | ||||
-rw-r--r-- | lld/ELF/Driver.h | 2 | ||||
-rw-r--r-- | lld/ELF/Options.td | 3 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 12 | ||||
-rw-r--r-- | lld/include/lld/Driver/Driver.h | 2 | ||||
-rw-r--r-- | lld/test/ELF/amdgpu-globals.s | 2 | ||||
-rw-r--r-- | lld/test/lit.cfg | 2 | ||||
-rw-r--r-- | lld/tools/lld/lld.cpp | 2 |
9 files changed, 27 insertions, 7 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 88dee03af9a..96eebac97bd 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -128,6 +128,7 @@ struct Configuration { bool ZNow; bool ZOrigin; bool ZRelro; + bool ExitEarly; bool ZWxneeded; DiscardPolicy Discard; SortSectionPolicy SortSection; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 207a2e580ec..d4915928040 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -39,7 +39,8 @@ using namespace lld::elf; Configuration *elf::Config; LinkerDriver *elf::Driver; -bool elf::link(ArrayRef<const char *> Args, raw_ostream &Error) { +bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly, + raw_ostream &Error) { HasError = false; ErrorOS = &Error; Argv0 = Args[0]; @@ -51,7 +52,7 @@ bool elf::link(ArrayRef<const char *> Args, raw_ostream &Error) { Driver = &D; ScriptConfig = &SC; - Driver->main(Args); + Driver->main(Args, CanExitEarly); InputFile::freePool(); return !HasError; } @@ -281,7 +282,7 @@ static uint64_t getZOptionValue(opt::InputArgList &Args, StringRef Key, return Default; } -void LinkerDriver::main(ArrayRef<const char *> ArgsArr) { +void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) { ELFOptTable Parser; opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); if (Args.hasArg(OPT_help)) { @@ -290,6 +291,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr) { } if (Args.hasArg(OPT_version)) outs() << getLLDVersion() << "\n"; + Config->ExitEarly = CanExitEarly && !Args.hasArg(OPT_full_shutdown); if (const char *Path = getReproduceOption(Args)) { // Note that --reproduce is a debug option so you can ignore it diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h index 5cd0bc1f64f..faa61a53b5e 100644 --- a/lld/ELF/Driver.h +++ b/lld/ELF/Driver.h @@ -27,7 +27,7 @@ extern class LinkerDriver *Driver; class LinkerDriver { public: - void main(ArrayRef<const char *> Args); + void main(ArrayRef<const char *> Args, bool CanExitEarly); void addFile(StringRef Path); void addLibrary(StringRef Name); llvm::LLVMContext Context; // to parse bitcode files diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index 0e13cdb16ff..0174d2126f5 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -80,6 +80,9 @@ def fatal_warnings: F<"fatal-warnings">, def fini: S<"fini">, MetaVarName<"<symbol>">, HelpText<"Specify a finalizer function">; +def full_shutdown : F<"full-shutdown">, + HelpText<"Perform a full shutdown instead of calling _exit">; + def format: J<"format=">, MetaVarName<"<input-format>">, HelpText<"Change the input format of the inputs following this option">; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 7728941c9db..e156f3c386c 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -23,6 +23,10 @@ #include "llvm/Support/raw_ostream.h" #include <climits> +#if !defined(_MSC_VER) && !defined(__MINGW32__) +#include <unistd.h> +#endif + using namespace llvm; using namespace llvm::ELF; using namespace llvm::object; @@ -316,6 +320,14 @@ template <class ELFT> void Writer<ELFT>::run() { return; if (auto EC = Buffer->commit()) error(EC, "failed to write to the output file"); + if (Config->ExitEarly) { + // Flush the output streams and exit immediately. A full shutdown is a good + // test that we are keeping track of all allocated memory, but actually + // freeing it is a wast of time in a regular linker run. + outs().flush(); + errs().flush(); + _exit(0); + } } template <class ELFT> diff --git a/lld/include/lld/Driver/Driver.h b/lld/include/lld/Driver/Driver.h index 312f4f812b7..a3265c85716 100644 --- a/lld/include/lld/Driver/Driver.h +++ b/lld/include/lld/Driver/Driver.h @@ -19,7 +19,7 @@ bool link(llvm::ArrayRef<const char *> Args); } namespace elf { -bool link(llvm::ArrayRef<const char *> Args, +bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly, llvm::raw_ostream &Diag = llvm::errs()); } diff --git a/lld/test/ELF/amdgpu-globals.s b/lld/test/ELF/amdgpu-globals.s index 7f46b989b95..f30c0ed4015 100644 --- a/lld/test/ELF/amdgpu-globals.s +++ b/lld/test/ELF/amdgpu-globals.s @@ -1,5 +1,5 @@ # RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o -# RUN: lld -flavor gnu %t.o -o %t +# RUN: ld.lld %t.o -o %t # RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s # REQUIRES: amdgpu diff --git a/lld/test/lit.cfg b/lld/test/lit.cfg index 3c7fa5d7ac1..91813a7575c 100644 --- a/lld/test/lit.cfg +++ b/lld/test/lit.cfg @@ -150,6 +150,8 @@ if config.test_exec_root is None: NoPreJunk = r"(?<!(-|\.|/))" NoPostJunk = r"(?!(-|\.))" +config.substitutions.append( (r"\bld.lld\b", 'ld.lld --full-shutdown') ) + tool_patterns = [r"\bFileCheck\b", r"\bnot\b", NoPreJunk + r"\blld\b" + NoPostJunk, diff --git a/lld/tools/lld/lld.cpp b/lld/tools/lld/lld.cpp index 99f3d2d85bf..0c32ff19299 100644 --- a/lld/tools/lld/lld.cpp +++ b/lld/tools/lld/lld.cpp @@ -101,7 +101,7 @@ int main(int Argc, const char **Argv) { std::vector<const char *> Args(Argv, Argv + Argc); switch (parseFlavor(Args)) { case Gnu: - return !elf::link(Args); + return !elf::link(Args, true); case WinLink: return !coff::link(Args); case Darwin: |