diff options
author | Alexandre Ganea <alexandre.ganea@legionlabs.com> | 2022-01-15 21:47:54 -0500 |
---|---|---|
committer | Alexandre Ganea <alexandre.ganea@legionlabs.com> | 2022-01-16 08:57:57 -0500 |
commit | f860fe362282ed69b9d4503a20e5d20b9a041189 (patch) | |
tree | 1f85d88798f7bd31cae0059d71c3c7817333afd6 /lld/tools | |
parent | 070d1034da87c94d86d1a61245ecf068141fdf14 (diff) | |
download | llvm-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.cpp | 49 |
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()); |