1 //===- tools/lld/lld.cpp - Linker Driver Dispatcher -----------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the main function of the lld executable. The main 10 // function is a thin wrapper which dispatches to the platform specific 11 // driver. 12 // 13 // lld is a single executable that contains four different linkers for ELF, 14 // COFF, WebAssembly and Mach-O. The main function dispatches according to 15 // argv[0] (i.e. command name). The most common name for each target is shown 16 // below: 17 // 18 // - ld.lld: ELF (Unix) 19 // - ld64: Mach-O (macOS) 20 // - lld-link: COFF (Windows) 21 // - ld-wasm: WebAssembly 22 // 23 // lld can be invoked as "lld" along with "-flavor" option. This is for 24 // backward compatibility and not recommended. 25 // 26 //===----------------------------------------------------------------------===// 27 28 #include "lld/Common/Driver.h" 29 #include "lld/Common/ErrorHandler.h" 30 #include "lld/Common/Memory.h" 31 #include "llvm/ADT/STLExtras.h" 32 #include "llvm/ADT/SmallVector.h" 33 #include "llvm/ADT/Twine.h" 34 #include "llvm/Support/CommandLine.h" 35 #include "llvm/Support/CrashRecoveryContext.h" 36 #include "llvm/Support/LLVMDriver.h" 37 #include "llvm/Support/Path.h" 38 #include "llvm/Support/PluginLoader.h" 39 #include "llvm/Support/Process.h" 40 #include "llvm/TargetParser/Host.h" 41 #include "llvm/TargetParser/Triple.h" 42 #include <cstdlib> 43 #include <optional> 44 45 using namespace lld; 46 using namespace llvm; 47 using namespace llvm::sys; 48 49 namespace lld { 50 extern bool inTestOutputDisabled; 51 52 // Bypass the crash recovery handler, which is only meant to be used in 53 // LLD-as-lib scenarios. 54 int unsafeLldMain(llvm::ArrayRef<const char *> args, 55 llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS, 56 llvm::ArrayRef<DriverDef> drivers, bool exitEarly); 57 } // namespace lld 58 59 // When in lit tests, tells how many times the LLD tool should re-execute the 60 // main loop with the same inputs. When not in test, returns a value of 0 which 61 // signifies that LLD shall not release any memory after execution, to speed up 62 // process destruction. 63 static unsigned inTestVerbosity() { 64 unsigned v = 0; 65 StringRef(getenv("LLD_IN_TEST")).getAsInteger(10, v); 66 return v; 67 } 68 69 #if 1 70 // On FreeBSD we only build the ELF linker. 71 LLD_HAS_DRIVER(elf) 72 #undef LLD_ALL_DRIVERS 73 #define LLD_ALL_DRIVERS { {lld::Gnu, &lld::elf::link} } 74 #else 75 LLD_HAS_DRIVER(coff) 76 LLD_HAS_DRIVER(elf) 77 LLD_HAS_DRIVER(mingw) 78 LLD_HAS_DRIVER(macho) 79 LLD_HAS_DRIVER(wasm) 80 #endif 81 82 int lld_main(int argc, char **argv, const llvm::ToolContext &) { 83 sys::Process::UseANSIEscapeCodes(true); 84 85 if (::getenv("FORCE_LLD_DIAGNOSTICS_CRASH")) { 86 llvm::errs() 87 << "crashing due to environment variable FORCE_LLD_DIAGNOSTICS_CRASH\n"; 88 LLVM_BUILTIN_TRAP; 89 } 90 91 ArrayRef<const char *> args(argv, argv + argc); 92 93 // Not running in lit tests, just take the shortest codepath with global 94 // exception handling and no memory cleanup on exit. 95 if (!inTestVerbosity()) { 96 int r = 97 lld::unsafeLldMain(args, llvm::outs(), llvm::errs(), LLD_ALL_DRIVERS, 98 /*exitEarly=*/true); 99 return r; 100 } 101 102 std::optional<int> mainRet; 103 CrashRecoveryContext::Enable(); 104 105 for (unsigned i = inTestVerbosity(); i > 0; --i) { 106 // Disable stdout/stderr for all iterations but the last one. 107 inTestOutputDisabled = (i != 1); 108 109 // Execute one iteration. 110 auto r = lldMain(args, llvm::outs(), llvm::errs(), LLD_ALL_DRIVERS); 111 if (!r.canRunAgain) 112 exitLld(r.retCode); // Exit now, can't re-execute again. 113 114 if (!mainRet) { 115 mainRet = r.retCode; 116 } else if (r.retCode != *mainRet) { 117 // Exit now, to fail the tests if the result is different between runs. 118 return r.retCode; 119 } 120 } 121 return *mainRet; 122 } 123