summaryrefslogtreecommitdiff
path: root/lld/tools
diff options
context:
space:
mode:
authorAlexandre Ganea <alexandre.ganea@legionlabs.com>2022-01-15 21:47:54 -0500
committerAlexandre Ganea <alexandre.ganea@legionlabs.com>2022-01-16 08:57:57 -0500
commitf860fe362282ed69b9d4503a20e5d20b9a041189 (patch)
tree1f85d88798f7bd31cae0059d71c3c7817333afd6 /lld/tools
parent070d1034da87c94d86d1a61245ecf068141fdf14 (diff)
downloadllvm-f860fe362282ed69b9d4503a20e5d20b9a041189.tar.gz
[LLD] Remove global state in lldCommon
Move all variables at file-scope or function-static-scope into a hosting structure (lld::CommonLinkerContext) that lives at lldMain()-scope. Drivers will inherit from this structure and add their own global state, in the same way as for the existing COFFLinkerContext. See discussion in https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html Differential Revision: https://reviews.llvm.org/D108850
Diffstat (limited to 'lld/tools')
-rw-r--r--lld/tools/lld/lld.cpp49
1 files changed, 33 insertions, 16 deletions
diff --git a/lld/tools/lld/lld.cpp b/lld/tools/lld/lld.cpp
index cad97f2153c2..7cf55e91d30e 100644
--- a/lld/tools/lld/lld.cpp
+++ b/lld/tools/lld/lld.cpp
@@ -87,6 +87,8 @@ static bool isPETarget(std::vector<const char *> &v) {
// Expand response files (arguments in the form of @<filename>)
// to allow detecting the -m argument from arguments in them.
SmallVector<const char *, 256> expandedArgs(v.data(), v.data() + v.size());
+ BumpPtrAllocator a;
+ StringSaver saver(a);
cl::ExpandResponseFiles(saver, getDefaultQuotingStyle(), expandedArgs);
for (auto it = expandedArgs.begin(); it + 1 != expandedArgs.end(); ++it) {
if (StringRef(*it) != "-m")
@@ -134,27 +136,43 @@ static Flavor parseFlavor(std::vector<const char *> &v) {
return parseProgname(arg0);
}
+static bool inTestOutputDisabled = false;
+
/// Universal linker main(). This linker emulates the gnu, darwin, or
/// windows linker based on the argv[0] or -flavor option.
static int lldMain(int argc, const char **argv, llvm::raw_ostream &stdoutOS,
llvm::raw_ostream &stderrOS, bool exitEarly = true) {
std::vector<const char *> args(argv, argv + argc);
- switch (parseFlavor(args)) {
- case Gnu:
- if (isPETarget(args))
- return !mingw::link(args, exitEarly, stdoutOS, stderrOS);
- return !elf::link(args, exitEarly, stdoutOS, stderrOS);
- case WinLink:
- return !coff::link(args, exitEarly, stdoutOS, stderrOS);
- case Darwin:
- return !macho::link(args, exitEarly, stdoutOS, stderrOS);
- case Wasm:
- return !lld::wasm::link(args, exitEarly, stdoutOS, stderrOS);
- default:
+ auto link = [&args]() {
+ Flavor f = parseFlavor(args);
+ if (f == Gnu && isPETarget(args))
+ return mingw::link;
+ if (f == Gnu)
+ return elf::link;
+ if (f == WinLink)
+ return coff::link;
+ if (f == Darwin)
+ return macho::link;
+ if (f == Wasm)
+ return lld::wasm::link;
die("lld is a generic driver.\n"
"Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld"
" (WebAssembly) instead");
- }
+ }();
+ // Run the driver. If an error occurs, false will be returned.
+ int r = !link(args, stdoutOS, stderrOS, exitEarly, inTestOutputDisabled);
+
+ // Exit immediately if we don't need to return to the caller.
+ // This saves time because the overhead of calling destructors
+ // for all globally-allocated objects is not negligible.
+ if (exitEarly)
+ exitLld(r);
+
+ // Delete the global context and clear the global context pointer, so that it
+ // cannot be accessed anymore.
+ CommonLinkerContext::destroy();
+
+ return r;
}
// Similar to lldMain except that exceptions are caught.
@@ -176,7 +194,7 @@ SafeReturn lld::safeLldMain(int argc, const char **argv,
// Cleanup memory and reset everything back in pristine condition. This path
// is only taken when LLD is in test, or when it is used as a library.
llvm::CrashRecoveryContext crc;
- if (!crc.RunSafely([&]() { errorHandler().reset(); })) {
+ if (!crc.RunSafely([&]() { CommonLinkerContext::destroy(); })) {
// The memory is corrupted beyond any possible recovery.
return {r, /*canRunAgain=*/false};
}
@@ -207,8 +225,7 @@ int main(int argc, const char **argv) {
for (unsigned i = inTestVerbosity(); i > 0; --i) {
// Disable stdout/stderr for all iterations but the last one.
- if (i != 1)
- errorHandler().disableOutput = true;
+ inTestOutputDisabled = (i != 1);
// Execute one iteration.
auto r = safeLldMain(argc, argv, llvm::outs(), llvm::errs());