summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp8
-rw-r--r--lld/ELF/Driver.h2
-rw-r--r--lld/ELF/Options.td3
-rw-r--r--lld/ELF/Writer.cpp12
-rw-r--r--lld/include/lld/Driver/Driver.h2
-rw-r--r--lld/test/ELF/amdgpu-globals.s2
-rw-r--r--lld/test/lit.cfg2
-rw-r--r--lld/tools/lld/lld.cpp2
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:
OpenPOWER on IntegriCloud